美文网首页
iOS的毛玻璃效果

iOS的毛玻璃效果

作者: 太郎君 | 来源:发表于2016-06-30 22:11 被阅读161次

    系统控件

    苹果在iOS7很多系统界面中都使用了毛玻璃效果,增加了界面的美观性,具有该效果的控件有

    • UINavigationBar
    • UIToolBar
    • UIToolbar

    这些控件的毛玻璃效果是基于同一套高斯模糊算法,为了问题的简单化,下文只对UINavigationBar进行分析。

    相信很多人遇到过如下的问题:

    • navigationBar.translucent为NO时,无高斯模糊,生硬
    • navigationBar.translucent为YES时,有高斯模糊,颜色会变浅

    预计效果


    Paste_Image.png

    实际效果


    Paste_Image.png

    根本原因是系统所用的高斯模糊算法会对色值进行一个转化,从设置值到表现值的转化关系如下

    y = (x - 102) / 0.6; // 设置值y的范围[0, 255]
    y = (x - 0.4) / 0.6; // 设置值y的范围[0, 1.0]
    

    这样导致表现值无法覆盖完整的色域

    x = 0.6y + 102; // 表现值x均>=102
    x = 0.6y + 0.4; // 表现值x均>=0.4
    

    解决方案有两种

    方案一:盖一个layer到navigationBar上,色彩叠加
    方案二:盖一个layer到navigationBar上,直接显示

    色彩叠加方案

    layer1:navigationBar的设置值y1,表现值l1,满足l1 = 0.6y1 + 0.4
    layer2:stickView的透明度a,表现值l2,设置值待求
    叠加后色值: (1 - a) * l1 + a * l2 = (1 - a) * (0.6 * y1 + 0.4) + a * l2
    所设即所得就是叠加后色值==y1,也就是 (1 - a) * (0.6 * y1 + 0.4) + a * l2 = y1
    可推导出:l2 = 0.4 * y1 / a + 0. 6 * y1 + 0.4 - 0.4 / a
    为了保证 l2 > 0
    可推导出:a > (0.4 - 0.4 * y1) / (0.6 * y1 + 0.4)
    

    相关代码

    - (CGFloat)minOpacityForValue:(CGFloat)value
    {
        return (0.4 - 0.4 * value) / (0.6 * value + 0.4);
    }
    
    - (CGFloat)convertValue:(CGFloat)value withOpacity:(CGFloat)opacity
    {
        return 0.4 * value / opacity + 0.6 * value - 0.4 / opacity + 0.4;
    }
    

    直接显示方法

    自定义控件

    苹果在iOS8后新增了UIBlurEffect类和UIVisualEffectView类,可以更简单高效地实现毛玻璃效果。

        UIImageView * imageView = [[UIImageView alloc] init];
        UIBlurEffect * blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
        UIVisualEffectView * effectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
        effectView.frame = imageView.bounds;
        effectView.alpha = 0.5f;
        [imageView addSubview:effectView];
    

    参考资料

    相关文章

      网友评论

          本文标题:iOS的毛玻璃效果

          本文链接:https://www.haomeiwen.com/subject/uplfjttx.html