You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS绘图APP:如何为UIBezierPath开放路径添加圆角?

iOS开放路径添加圆角实现方案

在iOS中没有像Android cornerPathEffect那样直接的API,但可以通过两种方式实现开放路径的圆角效果:

方法一:手动构建带圆角的UIBezierPath

针对开放路径的每个转角,用圆弧替换尖角,适合需要精确控制的场景。以下是处理触摸点数组生成圆角路径的示例代码:

func createRoundedOpenPath(from points: [CGPoint], cornerRadius: CGFloat) -> UIBezierPath? {
    guard points.count >= 2 else { return nil }
    let path = UIBezierPath()
    path.move(to: points[0])
    
    for i in 1..<points.count {
        let currentPoint = points[i]
        if i == 1 {
            path.addLine(to: currentPoint)
            continue
        }
        let prevPoint = points[i-1]
        let prevPrevPoint = points[i-2]
        
        // 计算线段方向向量
        let vector1 = CGVector(dx: prevPoint.x - prevPrevPoint.x, dy: prevPoint.y - prevPrevPoint.y)
        let vector2 = CGVector(dx: currentPoint.x - prevPoint.x, dy: currentPoint.y - prevPoint.y)
        
        // 计算夹角与圆弧参数
        let angle1 = atan2(vector1.dy, vector1.dx)
        let angle2 = atan2(vector2.dy, vector2.dx)
        let halfAngle = (angle2 - angle1) / 2
        let offsetDistance = cornerRadius / tan(halfAngle)
        
        // 圆弧起点、终点与圆心
        let startPoint = CGPoint(
            x: prevPoint.x - offsetDistance * cos(angle1),
            y: prevPoint.y - offsetDistance * sin(angle1)
        )
        let endPoint = CGPoint(
            x: prevPoint.x - offsetDistance * cos(angle2),
            y: prevPoint.y - offsetDistance * sin(angle2)
        )
        let centerPoint = CGPoint(
            x: prevPoint.x + cornerRadius * cos(angle1 + .pi/2 + halfAngle),
            y: prevPoint.y + cornerRadius * sin(angle1 + .pi/2 + halfAngle)
        )
        
        path.addLine(to: startPoint)
        path.addArc(
            withCenter: centerPoint,
            radius: cornerRadius,
            startAngle: angle1 + .pi/2,
            endAngle: angle2 - .pi/2,
            clockwise: halfAngle > 0
        )
        path.addLine(to: currentPoint)
    }
    return path
}

方法二:利用CGPath描边生成圆角路径

通过系统API将原开放路径转换为带圆角描边的路径,实现更简洁:

func roundedStrokePath(for originalPath: CGPath, cornerRadius: CGFloat, lineWidth: CGFloat) -> CGPath? {
    let strokedPath = CGPathCreateMutableCopyByStrokingPath(
        originalPath,
        nil,
        lineWidth,
        CGLineCap.round,
        CGLineJoin.round,
        cornerRadius
    )
    return strokedPath
}

使用时将原开放路径传入,得到的strokedPath是带圆角的闭合路径,绘制时调用fill()即可(原路径的描边宽度需和传入的lineWidth一致)。

效果参考

路径圆角效果

内容的提问来源于stack exchange,提问作者Aprog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 11:31:05