用 Blend Mode 来让 Navigation Bar 骚气起来
最近又在更新 Best Before.app,算是把同步写好了,但是还是打算顺便更新一下 UI。之前加入了自定义分类的功能,还允许用户给分类设置一个颜色,但是这个颜色却没有什么实际的作用,在这次更新中我打算在 Navigation Bar 上面显示出这个颜色。
应该怎么显示呢,一开始我的想法是让分类名称的第一个字符设置为这个颜色。尽管 UINavigationBar
并没有给我们提供一个 API 去做这个事情,我们还是能够很暴力地从其众多的 subviews
的 subviews
当中,找到这些 UILabel
。如果 iOS 还没到 11,这就足够了,但是 iOS 11 中却引入了 Large Title,而即便我们修改了 Large Title 的 attributedString
,它也会在我们拖动底下的 scroll view 时打回原形。
很讨厌。
这时我想起了 Sketch 中 Blend Mode,在 Sketch 用 Blend Mode Lighten 能够将颜色附着在图标上,虽然没法简单地定位到刚好只覆盖到第一个字符,但好像也挺拉风的,于是我在 Sketch 里面做了一些修改。
那 iOS 上是否有这样的功能呢。
居然有,我们只需要在 UINavigationBar
上添加一个 CALayer
,并将其的 compositingFilter
赋值为 lightenBlendMode
就可以了。同时还要 observe Navigation Bar 的 frame
以随着它的高度变动修改这个 layer 的 path
。
1 | func createNavigationBarBlending() { |
最后我们只需要在显示分类列表时,修改 blendLayer
的 fillColor
就行了。值得一提的是 UINavigationBar.frame
恰好只包含到了 Large Title View,并不包括搜索框。
当然如果再花些功夫,也还是能让它只覆盖到第一个字符的,但是也没必要了吧。