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

SwiftUI中如何为饼图切片Shape添加圆角?

给SwiftUI饼图切片添加圆角的解决方案

要实现带圆角的饼图切片,核心是通过调整路径,在切片的外弧两端添加圆角圆弧,同时修正外弧的起止角度来适配圆角空间。以下是修改后的完整代码:

struct SliceShape: Shape {
    var startAngle: Double
    var endAngle: Double
    var cornerRadius: Double = 8 // 可自定义的圆角半径参数

    func path(in rect: CGRect) -> Path {
        var path = Path()
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let radius = min(rect.width/2, rect.height/2)
        
        // 限制圆角半径最大值,避免超出切片范围
        let safeCornerRadius = min(cornerRadius, radius * 0.5)
        
        // 计算角度偏移:根据圆角半径和外圆半径,算出需要缩短外弧的角度
        let angleOffset = safeCornerRadius > 0 ? asin(safeCornerRadius / radius) * 180 / .pi : 0
        
        // 调整外弧的起止角度,留出圆角的绘制空间
        let adjustedStartAngle = startAngle + angleOffset
        let adjustedEndAngle = endAngle - angleOffset
        
        // 计算外弧两端的顶点坐标,作为圆角圆弧的中心
        let startPoint = CGPoint(
            x: center.x + radius * cos(.degrees(startAngle)),
            y: center.y + radius * sin(.degrees(startAngle))
        )
        let endPoint = CGPoint(
            x: center.x + radius * cos(.degrees(endAngle)),
            y: center.y + radius * sin(.degrees(endAngle))
        )
        
        // 1. 绘制切片的主外弧
        path.addArc(center: center,
                    radius: radius,
                    startAngle: .degrees(adjustedStartAngle),
                    endAngle: .degrees(adjustedEndAngle),
                    clockwise: false)
        
        // 2. 绘制结束端的圆角圆弧
        path.addArc(center: endPoint,
                    radius: safeCornerRadius,
                    startAngle: .degrees(endAngle - 90),
                    endAngle: .degrees(adjustedEndAngle - 90),
                    clockwise: true)
        
        // 3. 绘制从结束圆角到中心的直线
        path.addLine(to: center)
        
        // 4. 绘制起始端的圆角圆弧
        path.addArc(center: startPoint,
                    radius: safeCornerRadius,
                    startAngle: .degrees(adjustedStartAngle + 90),
                    endAngle: .degrees(startAngle + 90),
                    clockwise: true)
        
        path.closeSubpath()
        
        return path
    }
}

struct PieSliceView_Previews: PreviewProvider {
    static var previews: some View {
        SliceShape(startAngle: 10, endAngle: 90, cornerRadius: 12)
            .frame(width: 150, height: 150)
            .foregroundColor(.blue)
    }
}

关键逻辑说明

  • 安全圆角半径:通过min(cornerRadius, radius * 0.5)限制圆角大小,防止圆角半径过大导致路径异常。
  • 角度偏移计算:利用三角函数asin(safeCornerRadius / radius)算出需要缩短外弧的角度,确保圆角能自然衔接外弧。
  • 路径构建顺序:先绘制主外弧,再依次绘制结束端圆角、到中心的直线、起始端圆角,最后闭合路径,保证切片的完整形态。

你可以通过调整cornerRadius参数来控制圆角的大小,适配不同的视觉需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:12:36