Swift UIButton 圆角 + 阴影

很多时候,我们都希望按钮更符合 iOS 的设计风格,这样会让应用的界面看起来不那么跳,就算设计的不好看,也不会显的与系统格格不入。

“我不是设计师,我不知道怎么设计好看——但尽可能贴近系统风格不是错误的选择。 ” —— by Router

那么对于 UIButton 来说,圆角+阴影应该是常态。

放一张图片

显然,这是最便宜的办法——实际上也最昂贵。它需要你为每一个按钮做一系列的圆角图片,这样虽然省去了用代码实时渲染的苦处,却需要你做大量的前期工作,比如默认情况下一个背景,高亮下又是一个背景……等等,还有不同的分辨率!(如果你做的是 universal 应用,那么这个数量是要再翻倍的)。

另外一个缺点就是一点你用了自动布局——而且按钮又不是等比例缩放的时候,天都塌下来了。

所以说,这不是我的选择。

用代码实现

显然,我们还是需要用代码来做这件事情,然后把圆角交给 cpu 实时渲染。

常见版本

常见的圆角版本是这样的:

这样可以,但是你要知道,如果你给 button 添加了背景色,那 layer 就无能为力了。

—— layer 不对 subview 生效。

这时候,就要加上这句来让圆角生效:

我们只要把多出的角切掉就好了。——接下来就麻烦了,你会发现添加的阴影是无效的,比如:

——因为我们把多出来的东西都切掉了!

有一种说法是在 iOS 7 以后不需要 layer.masksToBounds = true 也能圆角,但在特定的环境下还是有些不同,有时候需要,有时候就不需要,我自己用的时候 iOS 9 也还是需要这句才能显示圆角的——但在 storyboard 里直接设置运行时参数就不需要。

而且,如果你一个页面 button 很多的话(30个以上),那么由于 layer.masksToBounds = true 导致的离屏渲染会大大拖慢系统的运行速度,体现在系统动画丢帧上。

layer 的 backgroundColor

其实 layer 自身也有个背景色,我们完全可以用它来做 button 的背景色,那么这样的话就可以同时实现圆角和阴影了!

这样,阴影就不会被切掉了。

最后,我们还需要给 layer 光栅化,这样才能让 cpu 渲染的时候缓存已经渲染好的内容以便复用。这样一来,就能大大提升系统动画的运行效率,不再丢帧了。

——当然,如果你 button 本身数量就比较少,那大可不必理会。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.