去落格博客阅读完整排版的Swift UIButton 圆角 + 阴影
很多时候,我们都希望按钮更符合 iOS 的设计风格,这样会让应用的界面看起来不那么跳,就算设计的不好看,也不会显的与系统格格不入。
“我不是设计师,我不知道怎么设计好看——但尽可能贴近系统风格不是错误的选择。 ” —— by Router
那么对于 UIButton 来说,圆角+阴影应该是常态。
显然,这是最便宜的办法——实际上也最昂贵。它需要你为每一个按钮做一系列的圆角图片,这样虽然省去了用代码实时渲染的苦处,却需要你做大量的前期工作,比如默认情况下一个背景,高亮下又是一个背景……等等,还有不同的分辨率!(如果你做的是 universal 应用,那么这个数量是要再翻倍的)。
另外一个缺点就是一点你用了自动布局——而且按钮又不是等比例缩放的时候,天都塌下来了。
所以说,这不是我的选择。
显然,我们还是需要用代码来做这件事情,然后把圆角交给 cpu 实时渲染。
常见的圆角版本是这样的:
button.layer.cornerRadius = 5.0
这样可以,但是你要知道,如果你给 button 添加了背景色,那 layer 就无能为力了。
—— layer 不对 subview 生效。
这时候,就要加上这句来让圆角生效:
button.layer.masksToBounds = true
我们只要把多出的角切掉就好了。——接下来就麻烦了,你会发现添加的阴影是无效的,比如:
button.layer.shadowColor = UIColor.blackColor().CGColor button.layer.shadowRadius = 2 button.layer.shadowOffset = CGSize(width: 2, height: 2) button.layer.shadowOpacity = 0.3
——因为我们把多出来的东西都切掉了!
有一种说法是在 iOS 7 以后不需要
layer.masksToBounds = true也能圆角,但在特定的环境下还是有些不同,有时候需要,有时候就不需要,我自己用的时候 iOS 9 也还是需要这句才能显示圆角的——但在 storyboard 里直接设置运行时参数就不需要。
而且,如果你一个页面 button 很多的话(30个以上),那么由于
layer.masksToBounds = true导致的离屏渲染会大大拖慢系统的运行速度,体现在系统动画丢帧上。
其实 layer 自身也有个背景色,我们完全可以用它来做 button 的背景色,那么这样的话就可以同时实现圆角和阴影了!
button.layer.cornerRadius = 5.0 //button.layer.masksToBounds = true button.layer.shadowColor = UIColor.blackColor().CGColor button.layer.shadowRadius = 2 button.layer.shadowOffset = CGSize(width: 2, height: 2) button.layer.shadowOpacity = 0.3 //button.backgroundColor = UIColor.greenColor() button.layer.backgroundColor = UIColor.blueColor().CGColor
这样,阴影就不会被切掉了。
最后,我们还需要给 layer 光栅化,这样才能让 cpu 渲染的时候缓存已经渲染好的内容以便复用。这样一来,就能大大提升系统动画的运行效率,不再丢帧了。
——当然,如果你 button 本身数量就比较少,那大可不必理会。
layer.shouldRasterize = true