【问题标题】:UIVibrancyEffect On iOS 7iOS 7 上的 UIVibrancyEffect
【发布时间】: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),否则我相当枯燥的建议是只针对最新的操作系统。不过,我有兴趣听到相反的观点。

标签: ios objective-c uiview uiimage


【解决方案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,因为这会重新渲染蒙版并应用它。希望这对每个人都有帮助。

【讨论】:

    猜你喜欢
    • 2015-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多