SwiftUI实现带圆角的Donut Chart(环形图)的方法咨询

实现思路
你要的圆角效果本质是给饼图/环形图切片的端点做圆弧平滑处理,不需要改动现有arc绘制的核心逻辑,这里提供两种最常用的实现方案,按需选择即可:
方案1:用lineCap属性快速实现(通用最优方案,代码量最小)
这个方案不需要手动计算圆角坐标,靠系统内置API直接实现圆角,性能最高,同时支持实心饼图和环形图切换,完全匹配你示例图的效果:
struct SliceData { var startAngle: Angle var endAngle: Angle var color: Color // 控制环形宽度,设为视图半径一半即可实现实心饼图 var lineWidth: CGFloat = 30 } struct RoundedSliceView: View { var sliceData: SliceData var body: some View { GeometryReader { geometry in let size = min(geometry.size.width, geometry.size.height) let center = CGPoint(x: size/2, y: size/2) // 半径减去线宽的一半,避免描边超出画布范围 let radius = size/2 - sliceData.lineWidth/2 Path { path in path.addArc(center: center, radius: radius, startAngle: Angle(degrees: -90) + sliceData.startAngle, endAngle: Angle(degrees: -90) + sliceData.endAngle, clockwise: false) } .stroke(sliceData.color, style: StrokeStyle( lineWidth: sliceData.lineWidth, lineCap: .round // 这行是实现圆角效果的核心 )) } .aspectRatio(1, contentMode: .fit) } }
你可以直接用以下代码测试效果:
struct TestChartView: View { var body: some View { ZStack { RoundedSliceView(sliceData: SliceData( startAngle: .degrees(0), endAngle: .degrees(120), color: .blue )) RoundedSliceView(sliceData: SliceData( startAngle: .degrees(120), endAngle: .degrees(240), color: .red )) RoundedSliceView(sliceData: SliceData( startAngle: .degrees(240), endAngle: .degrees(360), color: .green )) } .padding(50) } }
方案2:自定义Path绘制圆角(适合高自定义需求场景)
如果你需要单独控制圆角大小、或者需要给切片靠近圆心的角也加圆角,就可以用这个方案:
- 先计算切片两个侧边的偏移量,把侧边向内收留出圆角位置
- 在四个端点(内外弧各两个端点)处分别添加小圆弧做圆角,再连接原有路径即可
这个方案灵活性更高,但需要手动处理角度和坐标计算,适合对样式有特殊要求的场景。
内容的提问来源于stack exchange,提问作者gcas
相关产品推荐
相关产品推荐

