ios - iOS 7 上的 UIVibrancyEffect

标签 ios objective-c uiview uiimage

所以我一直在尝试 iOS 8 beta 并在我的应用程序需要它们的地方实现新的 UIEffectViews。现在我遇到了一个问题,我仍然希望向后兼容 iOS 7,但要保持活力效果,因为它确实有助于提高可读性。我过去曾使用 UIToolbars 来获得模糊效果,它们效果很好,但不是为了增加活力。我想我会子类化 UIView 并添加一个工具栏 subview ,然后做一些巧妙的渲染来实现看起来像这样的活力效果: 1. 将工具栏渲染为 UIImage 2. 将充满活力的内容渲染到 UIImage 3. 将工具栏图像 mask 到充满活力的内容图像 mask 4.饱和度和亮度困惑 5. 让 UIView 的 subview 在工具栏上显示最终结果

我已经尝试在 UIView 的 drawRect: 中执行此操作,但它不想重绘每一帧,并且设置计时器确实会干扰动画,即使渲染时间不是很长。如果有人能指出示例代码或开源库,我将不胜感激。

谢谢。

最佳答案

所以我从未发布过答案,但我确实弄明白了。

我尝试的蛮力方法是使用 Core Image 效果。我会将 super View 渲染为 UIImage,对其进行模糊处理,然后将其覆盖在具有深色样式的工具栏上。这看起来不错,但即使在我的 5S 上的 GPU 上下文中,它也非常慢,所以它不可能在其他设备上运行。这是我能看到的最好的效果,对于静态内容来说效果很好,但对于实时内容来说并不实用。

我能够实现实时版本,但它看起来不太好。基本上我所做的是将所有充满活力的内容渲染成图像并将其用作 View 的 mask 。然后我使 View 几乎不可见(如 .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

如果您想动态更新活力 View 中的内容,您可以调用 forceVibrancyUpdate,因为这会重新渲染 mask 并应用它。希望对大家有所帮助。

关于ios - iOS 7 上的 UIVibrancyEffect,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24399415/

相关文章:

ios - 如何在隐藏或取消隐藏时为 UIView 设置动画

ios - 在 iOS 中从 map 生成图像

ios - 具有自定义 UIView(包括按钮)的 UIViewController 无法识别水龙头

ios - UIControl 触摸 VC 左侧的行为不正确

ios - NSURLConnection 在 iOS 6 上超时但在 iOS 5 上不超时

ios - UIStoryboard 更改标签栏按钮文本

iphone - 为什么这段 Objective C 代码会泄漏内存?

android - 在 Flutter 中将图像转换为 XFile

ios - 压缩 Xcode 项目

iOS - IB 中的 UILabel attributedText 无法更改字体大小