Sample project .gif (4.4MB)
iOS 7 引入了一个新的高效快照 API。7blur 项目基于这些框架生成类似于控制中心和通知中心的模糊效果,强制实施 iOS 7 应用的第 3 个设计模式 —— 深度。需要注意的是,iOS 7 已经达到 GM (11A465) 状态。这个特定的 API 在 2013 年的 WWDC 上进行了公开讨论,7blur 可由社区自由使用和改进。
7blur 支持两种模糊风格、两种定位风格以及许多模糊颜色组件。
支持的模糊效果
支持的位置
模糊颜色组件
通过结合上述属性,可以生成许多希望的可视效果和用户界面。7blur 只拥有少数 API 任务,并且可以在 Interface Builder 中对视图内容进行可视化编辑以提高生产力。下一部分将介绍 API,然后是包含在示例项目中的常见用例。让我们开始吧!
7blur 只需要 iOS 7 和 Xcode 5。集成很简单,包括 3 个任务。 (1) 加载 BLRView
并可能将其滑动到合适位置生成下拉菜单风格,(2) 使用颜色组件进行模糊,最后 (3) 卸载 BLRView
来移除。以下是 API 的参考列表,Xcode 5 项目中也包含了结构化注释(Doxygen)。
BLRView.h
//Drop down menu style
+ (BLRView *) load:(UIView *) view;
//Fixed position style
+ (BLRView *) loadWithLocation:(CGPoint) point parent:(UIView *) view;
//Remove
- (void) unload;
//Down
- (void) slideDown;
//Up
- (void) slideUp;
//Static blur
- (void) blurWithColor:(BLRColorComponents *) components;
//Live real time blur
- (void) blurWithColor:(BLRColorComponents *) components updateInterval:(float) interval;
示例 Xcode 5 项目包含 (3) 个常见的 iOS 7 用例,并支持通话状态栏、iPhone 4"和3.5"视网膜设备。
这是下拉菜单风格实时模糊的示例。背景内容在前台实时模糊。
LiveBlurVC.m
- (void) viewDidLoad {
[super viewDidLoad];
...
//Load BLRView with UITableView as background content
self.blrView = [BLRView load:self.tableView];
//Add BLRView to main view
[self.view addSubview:self.blrView];
}
- (IBAction) toggleViewDirection:(id) sender {
switch (self.viewDirection) {
case KShouldMoveDown: {
//Start live real time blur with .2f update interval
[self.blrView blurWithColor:[BLRColorComponents lightEffect] updateInterval:.2f];
//Slide down - drop down style
[self.blrView slideDown];
...
}
case KShouldMoveUp: {
//Slide up
[self.blrView slideUp];
...
}
...
}
}
类似于上面的示例,但这个版本停止了UITableView
的滚动,渐入轮廓图,然后下拉一个静态模糊视图。背景内容使用前景后的深色模糊,同时禁用触摸事件。
StaticBlurVC.m
- (void) viewDidLoad {
[super viewDidLoad];
...
//Load BLRView with UITableView as background content
self.blrView = [BLRView load:self.tableView];
...
//Add BLRView to main view
[self.view addSubview:self.blrView];
}
- (IBAction) toggleViewDirection:(id) sender {
switch (self.viewDirection) {
case KShouldMoveDown: {
//Stop UITableView : UIScrollView from scrolling
[self.tableView setContentOffset:self.tableView.contentOffset animated:NO];
//Show vignette
[UIView animateWithDuration:.2f animations:^{
self.blackoutView.alpha = .2f;
} completion:^(BOOL finished) {
}];
//Static blur with dark color components
[self.blrView blurWithColor:[BLRColorComponents darkEffect]];
//Slide down - drop down style
[self.blrView slideDown];
...
}
case KShouldMoveUp: {
//Hide vignette
[UIView animateWithDuration:.5f animations:^{
self.blackoutView.alpha = 0;
} completion:^(BOOL finished) {
}];
//Slide up
[self.blrView slideUp];
...
}
...
}
}
最后一个示例与先前两个示例不同的是,它支持在子视图中定位视图。
PositionedBlurVC.m
- (IBAction) toggleView:(id) sender {
switch (self.viewDisplayAction) {
case KShouldPresent: {
//Location point to place BLRView
CGPoint point = CGPointMake(0, 200);
//Load BLRView with UIView as background content
self.blrView = [BLRView loadWithLocation:point parent:self.backgroundView];
//Container foreground frame updated to match BLRView (x, y, w, h)
self.foregroundView.frame = CGRectMake(point.x, point.y, CGRectGetWidth(self.blrView.frame), CGRectGetHeight(self.blrView.frame));
//Add BLRView to foreground view
[self.foregroundView addSubview:self.blrView];
//Start live real time blur with .2f update interval
[self.blrView blurWithColor:[BLRColorComponents lightEffect] updateInterval:.2f];
...
}
case KShouldDismiss: {
//Remove BLRView
[self.blrView unload];
...
}
...
}
}
所有示例都卸载或从视图层次结构中移除BLRView
。
- (void) viewWillDisappear:(BOOL) animated {
//Remove BLRView if not done previously
[self.blrView unload];
}
7blur可以根据许多用例进行自定义,并在界面构建器中可视编辑以提高工作效率。这促进了MVC设计模式并提高了效率。也可以通过子类化进行进一步的重用。
7blur在静态模糊和实时模糊方面表现平均。打开这个项目供社区使用的意图之一是改进这一点。在进行这些改进之前,让我们讨论一下7blur是如何工作的。
首先(1) 7blur使用iOS 7中新的UIView
(UISnapshotting)类别drawViewHierarchyInRect:afterScreenUpdates:
来获取快照。苹果在WWDC 2013 - Session 226中指出,这是首选的图形效果方法,而且速度很快。API在种子2中被重命名为snapshotView:
。
为了性能和实时快照,会丢弃屏幕更新的挂起任务。
原始 - 320x568
其次(2) 7blur从图形上下文以x1点缩放获取新的快照图像,并从BLRView
的帧属性裁剪背景快照。示例项目有一个尺寸为320x200的BLRView
。
裁剪 - 320x200
第三(3) 将裁剪的快照以x4的缩放因子缩小。
缩小 - 80x50
第四(4) 将缩小的图像应用模糊效果,使用的是苹果的UIImage+ImageEffects
UIImage
类别的一个修改版本。模糊操作通过使用上一步中的较小图像大小得到进一步改善。这个类别中的方法是快速的,包括以下来自Accelerate.framework的vImage函数:
应用模糊 - 80x50
通过UIImageView默认的内容模式缩放 - 320x200
最后,(5) 将模糊的快照分配给BLRView
的backgroundImageView
属性,默认的内容模式将其缩放回原始大小,并保留宽高比。
最终 - 320x568
快照必须在主线程上执行,而裁剪、缩放和模糊操作则卸载到后台全局队列。这些操作因使用了Accelerate.framework而快速。一旦完成,UI更改将在主运行循环上同步。在实时实时模糊实现中,优先使用低级的GCD调度计时器而不是NSTimer
。在iOS中,例如在UIScrollView
滚动等某些 cocoa touch事件中会抑制NSTimer
事件。通过使用GCD调度计时器,即使在这样的事件中也能实现实时模糊效果。CADisplayLink
在NSRunLoopCommonModes
中也是一个不错的选择。
在iOS 7的控制中心、通知中心、状态栏、键盘下以及其他视图中,Apple的实时模糊效果流畅且高效。这是因为UIKit建立在OpenGL之上。Apple拥有私有的API,可以监听子视图的重新绘制周期,从而消除了无效效率轮询的需求。即使背景内容没有改变或失效,示例项目也会占用实时模糊所需的资源。苹果无需为此支付“税收”。
此外,Apple的模糊效果在硬件中实现。即使使用Accelerate.framework和vImage处理,仍然是CPU/GPU混合实现。虽然存在这些限制,但开源社区仍有改进像7blur这样的项目的机会。请进行分叉并改进。
MIT许可(MIT)
版权所有(c)2013 Justin M Fischer
以下权限已授予,无需支付费用,即可向任何获取软件副本及其相关文档(“软件”)的个人提供软件,包括但不限于使用、复制、修改、合并、发布、分发、转让和/或销售软件副本,以及许可软件提供方据此将该软件提供给其他人使用,前提是以下条件:上述版权声明和本许可声明应包含在所有或大部分软件副本中。
软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、特定目的的适用性和非侵权性保证。在任何情况下,作者或版权持有者不对任何要求、损害或其他责任(无论属于合同、侵权或其他原因)承担责任,这些责任均产生自、产生于或与软件或软件的使用或其他交易有关。