iOS | UIBezierPath 圆角展示不全的问题及解决方案

我给一个高度为 40 的 view 设置底部两个半径为 40 的圆角:

let orangeView = UIView(frame: .init(x: 150, y: 100, width: 100, height: 40))
orangeView.backgroundColor = .orange
view.addSubview(orangeView)

let orangeViewPath = UIBezierPath.init(roundedRect: .init(x: 0, y: 0, width: 100, height: 40), byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: .init(width: 40, height: 40))
let orangeViewLayer = CAShapeLayer()
orangeViewLayer.frame = orangeView.bounds
orangeViewLayer.path = orangeViewPath.cgPath
orangeView.layer.mask = orangeViewLayer

效果如下:

很奇怪,圆角明明设置的是 40,结果却是 20。

查看文档得到答案:

cornerRadii
The radius of each corner oval. Values larger than half the rectangle’s width or height are clamped appropriately to half the width or height.

就是说当 radius 大于 Rect 宽或高一半的时候,radius 等于 Rect 宽或高的一半。
这就是为什么我设置 40 圆角却只展示了 20 的原因。

解决方案:

将 roundedRect 向上移的同时增加它的高度:

let orangeView = UIView(frame: .init(x: 150, y: 100, width: 100, height: 40))
orangeView.backgroundColor = .orange
view.addSubview(orangeView)

let orangeViewPath = UIBezierPath.init(roundedRect: .init(x: 0, y: -40, width: 100, height: 80), byRoundingCorners: [.bottomLeft, .bottomRight], cornerRadii: .init(width: 40, height: 40))
let orangeViewLayer = CAShapeLayer()
orangeViewLayer.frame = orangeView.bounds
orangeViewLayer.path = orangeViewPath.cgPath
orangeView.layer.mask = orangeViewLayer

效果:

还有一种更实用的方法,详情:

https://www.jianshu.com/p/a73e9bc3e30e

推荐阅读更多精彩内容