iOS 7 上的 UIVibrancyEffect
Posted
技术标签:
【中文标题】iOS 7 上的 UIVibrancyEffect【英文标题】:UIVibrancyEffect On iOS 7 【发布时间】:2014-06-25 02:46:20 【问题描述】:所以我一直在使用 ios 8 测试版并在我的应用需要它们的地方实现新的 UIEffectViews。现在我遇到了一个问题,我仍然希望向后兼容 iOS 7,但要保持活力效果,因为它确实有助于提高可读性。我过去曾使用 UIToolbars 来实现模糊效果,它们效果很好,但不适合活力。我想我会继承 UIView 并添加一个工具栏子视图,然后做一些巧妙的渲染来实现看起来像这样的活力效果: 1. 将工具栏渲染为 UIImage 2. 将充满活力的内容渲染到 UIImage 3.将工具栏图像蒙版为充满活力的内容图像蒙版 4.弄乱饱和度和亮度 5. 让 UIView 的子视图在工具栏上显示最终结果
我已经尝试在 UIView 的 drawRect: 中执行此操作,但它不想重绘每一帧,并且设置计时器确实会干扰动画,即使渲染时间不是很高。如果有人能指出示例代码或开源库,将不胜感激。
谢谢。
【问题讨论】:
我正在寻找同样的东西。目前,我已经为 iOS 7 实现了一个解决方法,我只是“扫描”(将其转换为 UIImage 并计算平均颜色)底层视图以确定是否需要在视图上显示白色或黑色文本。我知道结果不一样,但它会为我的目的工作。我想复制相同的活力效果将是一个 PITA。 @MarkusRautopuro 我最终只使用工具栏视图并将我想要充满活力的内容渲染为蒙版,然后将其覆盖到工具栏上。它不像ios8那样“活力”,但看起来也不错。 好的,听起来不错。您可以通过回答自己的问题来分享一些代码吗? @MarkusRautopuro 发布并用代码回答:) 这可能听起来很傻,但我可以问一下——为什么你还要提供支持 iOS 7 的更新?应用商店允许您的客户获取与他们的设备兼容的最新应用版本(即使它卡在 iOS 4 上),并且几乎所有可以升级的用户都会非常迅速地升级。因此,除非您要发布一个您希望旧版操作系统获得的关键错误修复(在这种情况下,请避免使用大量新 UI),否则我相当枯燥的建议是只针对最新的操作系统。不过,我有兴趣听到相反的观点。 【参考方案1】:所以我从未发布过答案,但我确实想通了。
我尝试的蛮力方法是使用 Core Image 效果。我会将超级视图渲染为 UIImage,对其进行模糊处理,然后将其覆盖在带有深色样式的工具栏上。这看起来很棒,但即使在我的 5S 上的 GPU 环境下,它也很慢,所以它无法在其他设备上运行。这是我能看到的最好的,并且对于静态内容非常有用,但对于实时来说并不实用。
我能够实现实时版本,但看起来不太好。基本上我所做的是将所有充满活力的内容渲染到图像中,并将其用作视图的蒙版。然后我使视图几乎不可见(如 0.2 alpha),然后将其放在工具栏上。它看起来不像 iOS8 或原始 CI 版本那样充满活力,但它运行良好且预成型良好。
这里有一些代码,如果你真的想要,你可以复制和粘贴:
-(instancetype)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
self.backgroundColor = [UIColor colorWithWhite:1 alpha:0.2];
maskingContents = [[UIView alloc] initWithFrame:self.bounds];
[self addSubview:maskingContents];
return self;
-(void)addSubview:(UIView *)view
if (![view isEqual:maskingContents])
[maskingContents setHidden:NO];
[maskingContents addSubview:view];
//now we need to mask it
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
[maskingContents.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* mask = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//apply the mask
CALayer* maskLayer = [CALayer layer];
maskLayer.frame = self.bounds;
[maskLayer setContents:(id)mask.CGImage];
[self.layer setMask:maskLayer];
[maskingContents setHidden:YES];
else [super addSubview:view];
-(void)forceVibrancyUpdate
[maskingContents setHidden:NO];
//now we need to mask it
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
[maskingContents.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* mask = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//apply the mask
CALayer* maskLayer = [CALayer layer];
maskLayer.frame = self.bounds;
[maskLayer setContents:(id)mask.CGImage];
[self.layer setMask:maskLayer];
[maskingContents setHidden:YES];
@end
如果您想动态更新活力视图中的内容,您可以调用 forceVibrancyUpdate,因为这会重新渲染蒙版并应用它。希望这对每个人都有帮助。
【讨论】:
以上是关于iOS 7 上的 UIVibrancyEffect的主要内容,如果未能解决你的问题,请参考以下文章
将 UIVibrancyEffect 添加到 UIScrollview
为了使模糊的 UIVibrancyEffect 起作用,我们是不是必须将其作为单独的视图添加到 UIBlurEffect 的 contentView 中?