JChat Swift 优化 - Blended Layers

作者: YxxxHao | 来源:发表于2017-10-18 23:44 被阅读83次

    最近一直在写公司里的开源项目 JChat ,这里记录下其中优化过程。

    什么是 Blended Layers(图层混合)

    这里举个例来说:

    class ViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
            let v1 = UIView(frame: view.frame)
            v1.backgroundColor = .red
    
            let v2 = UIView(frame: view.frame)
            v2.backgroundColor = .blue
            v2.alpha = 0.5
    
            view.addSubview(v1)
            view.addSubview(v2)
        }
    }
    

    在当前加页面上添加一个红色的 v1 和一个蓝色半透明的 v1,最终显示的是紫色:

    图片.png

    这就是图层混合了。这种情况下,系统是需要消耗 GPU 资源来计算最终显示的颜色,rgba 的混合计算公式如下:

    R(C) = (1-alpha)*R(B) + alpha*R(A)
    G(C) = (1-alpha)*G(B) + alpha*G(A)
    B(C) = (1-alpha)*B(B) + alpha*B(A)                 
    

    如何避免 Blended Layers

    如果判断应用中是否有图层的混合呢,其实 Xcode 已经集成了这个功能,我们可以直接运行在模拟器里面后,通过 Debug -> Color Blended Layers 开启:

    图片.png

    红色的部分说明存在图层混合,是需要我们去处理的地方式。

    一般情况下,导致图层混合的可能主要有:

    1. opaque 为 false
    2. 图层存在透明度
    3. 图层没有默认颜色
    4. UI 图片资源本身就存在透明的通道

    因为 UI 组件的 opaque 的默认值是 true,如果不是自己手动设置 false,一般都不是第一个原因导致的,看上面的 JChat 效果图,UILabel 中红色(图层混合)主要是因为 label 没有设置默认色导致的,所以我们需要设置下 label 的默认色:

    usernameLabel.backgroundColor = .white
    

    修改后我们再看效果:

    图片.png

    从上面发现,如果 label 的 text 是中文的话,还是会发生图层混合,那是因为 label 的内容是中文时,实际渲染区域要大于 label 的大小,最外层多了一个 sublayer,这时我们可以通过

    usernameLabel.layer.masksToBounds = true
    

    来解决这个问题,我们再来看效果图:

    图片.png

    上图中可以看到,其中一个资源图片发生了图层混合,这时明显就是 UI 的锅了,你就可以找你的 UI 妹子装逼了,如果你这觉得麻烦的话,自己打开 ps, 花上10秒自己修改下呗。突然又想起,以前的 UI 和自己扯了半小时,最后他花了两三分钟给我 p 了张图,然后搞定了-

    小结

    图层混合对性能的影响虽然不是特别大,但我们还是需要注意下的,积少成多,把每一步做好,才能更好地打造一款细滑般的应用。

    相关文章

      网友评论

      • 玉思盈蝶:我下载了你的这个开源项目JChat,在Xcode9上运行闪退,我用的8.3.2就可以,为什么呢?
        玉思盈蝶:@YxxxHao 哈哈。。不好意思,可以了,是JMAPPKEY没写
        YxxxHao:@玉思盈蝶 你把错误 信息发一下呗,我这里是没有问题的

      本文标题:JChat Swift 优化 - Blended Layers

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