如何为自定义UIBezierPath图形添加左上、右上圆角(滑块控制)
解决自定义UIBezierPath图形添加左上/右上圆角的问题
首先,咱们得先搞清楚为什么你之前的方法都不生效:
- 你用
UIBezierPath(roundedRect:byRoundingCorners:cornerRadii:)创建的路径是标准矩形,和你自定义的曲线路径完全不匹配,作为mask的话只会显示矩形的圆角区域,自然得不到你想要的效果。 - 给
CAShapeLayer设置cornerRadius只对矩形类路径生效,自定义曲线路径的边角系统无法自动识别,所以这个属性不会起作用。 - 直接给ImageView加圆角,作用的是ImageView本身的矩形layer,而非你绘制的自定义图形,所以也无效。
正确解决方案:手动修改自定义路径,添加圆角圆弧
既然你的图形是用自定义UIBezierPath绘制的,咱们直接在原路径的基础上,把左上、右上的直角替换成圆角圆弧即可。以下是修改后的完整代码:
// 定义圆角半径,可根据滑块值动态调整 var cornerRadius: CGFloat = 20.0 // 这里可以替换成你的滑块传入值 // 1. 创建带圆角的自定义路径 let bezierPath = UIBezierPath() // 处理右上圆角:从(360 - cornerRadius, 0)出发,绘制右上圆弧 bezierPath.move(to: CGPoint(x: 360 - cornerRadius, y: 0)) bezierPath.addArc(withCenter: CGPoint(x: 360 - cornerRadius, y: cornerRadius), radius: cornerRadius, startAngle: .pi * 3/2, endAngle: 0, clockwise: true) // 继续原有的曲线绘制(从右上圆弧终点到(360,75)) bezierPath.addCurve(to: CGPoint(x: 360, y: 75), controlPoint1: CGPoint(x: 359.53, y: 30.5), controlPoint2: CGPoint(x: 359.91, y: 55.45)) // 保留原路径的剩余曲线部分 bezierPath.addCurve(to: CGPoint(x: 360, y: 153.78), controlPoint1: CGPoint(x: 360.35, y: 153.21), controlPoint2: CGPoint(x: 360, y: 153.78)) bezierPath.addCurve(to: CGPoint(x: 180, y: 153.78), controlPoint1: CGPoint(x: 360, y: 153.78), controlPoint2: CGPoint(x: 271.2, y: 212.77)) bezierPath.addCurve(to: CGPoint(x: 0, y: 153.78), controlPoint1: CGPoint(x: 88.8, y: 94.8), controlPoint2: CGPoint(x: 0, y: 153.78)) // 处理左上圆角:从(0,153.78)到(0, cornerRadius),绘制左上圆弧 bezierPath.addLine(to: CGPoint(x: 0, y: cornerRadius)) bezierPath.addArc(withCenter: CGPoint(x: cornerRadius, y: cornerRadius), radius: cornerRadius, startAngle: .pi, endAngle: .pi * 3/2, clockwise: true) // 连接到右上圆角的起点,闭合路径 bezierPath.addLine(to: CGPoint(x: 360 - cornerRadius, y: 0)) bezierPath.close() // 2. 填充路径(如果是直接绘制在View上) UIColor.green.setFill() bezierPath.fill() // 3. 如果是作为ImageView的mask使用 let maskLayer = CAShapeLayer() maskLayer.path = bezierPath.cgPath self.imgTop.layer.mask = maskLayer
代码说明:
- 我们把原路径中左上(0,0)、右上(360,0)这两个直角,替换成了用
addArc(withCenter:...)绘制的圆弧。 - 圆弧的圆心、半径、起始/结束角度都是根据圆角半径计算的,确保圆角和原路径完美衔接。
- 你可以把
cornerRadius替换成滑块的实时值,就能实现动态调整圆角大小的效果。
另一种方法:路径交集(适合复杂图形)
如果你不想修改原路径,也可以通过原路径和圆角矩形路径取交集的方式得到最终路径:
// 1. 你的原自定义路径 let originalPath = UIBezierPath() // ... 这里是你原有的路径绘制代码 ... // 2. 创建带左上、右上圆角的矩形路径 let roundedRectPath = UIBezierPath(roundedRect: self.imgTop.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: cornerRadius, height: cornerRadius)) // 3. 取两个路径的交集 if let combinedCGPath = originalPath.cgPath.copy(using: CGPathTransform(intersect: roundedRectPath.cgPath)) { let finalPath = UIBezierPath(cgPath: combinedCGPath) // 设置mask let maskLayer = CAShapeLayer() maskLayer.path = finalPath.cgPath self.imgTop.layer.mask = maskLayer }
这种方法不需要修改原路径,适合图形比较复杂的场景,但要注意路径的坐标系要保持一致。
内容的提问来源于stack exchange,提问作者Khushbu Desai




