IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Swift UIButton 圆角 + 阴影

    R0uter发表于 2016-09-13 06:46:55
    love 0

    去落格博客阅读完整排版的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 的 backgroundColor

    其实 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

     

    Swift UIButton 圆角 + 阴影,首发于落格博客。

    其他推荐:
    1. Swift 2 中的 String 字符串
    2. 译:我如何在 Swift 声明 闭包?
    3. 在 Swift 里使用 SQLite 数据库
    4. Swift 里的 Stack 实现
    5. Swift 如何像 C语言 那样接收入口参数?



沪ICP备19023445号-2号
友情链接