SwiftUI中使用Trim实现带分段间隔与圆角的环形饼图
SwiftUI环形饼图实现问题
我需要实现设计师要求的环形饼图,目前已经能画出基础的环形分段,但卡在了分段间的间隔和圆角效果上——尝试添加边框无效,微调Trim参数来做间隔的话视觉效果很差。想请教下这个设计能不能在SwiftUI里实现,还是得让设计师调整方案?
我的现有实现代码:
import SwiftUI struct ContentView: View { @ObservedObject var charDataObj = ChartDataContainer() @State var indexOfTappedSlice = -1 var body: some View { VStack { Spacer() ZStack { Circle() .stroke(Color(hex: 0x2A3950), style: StrokeStyle(lineWidth: 100, lineCap: .round, lineJoin: .round)) .frame(width: 220, height: 270) ForEach(0..<charDataObj.chartData.count) { index in Circle() .trim(from: index == 0 ? 0.0 : charDataObj.chartData[index-1].value / 100, to: (charDataObj.chartData[index].value / 100)) .stroke(charDataObj.chartData[index].color, style: StrokeStyle(lineWidth: 50.0, lineCap: .butt, lineJoin: .round)) .rotationEffect(Angle(degrees: 270.0)) .onTapGesture { indexOfTappedSlice = indexOfTappedSlice == index ? -1 : index } .scaleEffect(index == indexOfTappedSlice ? 1.1 : 1.0) .animation(.spring()) } }.frame(width: 150, height: 150) Spacer() } .frame(maxWidth: .infinity) .background(Color(hex: 0x42506B)) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } //MARK:- Chart Data struct ChartData { var id = UUID() var color : Color var percent : CGFloat var value : CGFloat } @available(iOS 15.0, *) class ChartDataContainer : ObservableObject { @Published var chartData = [ChartData(color: .green, percent: 26, value: 0), ChartData(color: .blue, percent: 28, value: 0), ChartData(color: .white, percent: 23, value: 0), ChartData(color: .yellow, percent: 12, value: 0), ChartData(color: .red, percent: 11, value: 0),] init() { calc() } func calc(){ var value : CGFloat = 0 for i in 0..<chartData.count { value += chartData[i].percent chartData[i].value = value } } } extension Color { init(hex: Int, opacity: Double = 1.0) { let red = Double((hex & 0xff0000) >> 16) / 255.0 let green = Double((hex & 0xff00) >> 8) / 255.0 let blue = Double((hex & 0xff) >> 0) / 255.0 self.init(.sRGB, red: red, green: green, blue: blue, opacity: opacity) } }
我尝试过微调Trim参数来制造间隔,但效果很差,代码如下:
.trim(from: index == 0 ? 0.003: (charDataObj.chartData[index-1].value / 100) + 0.003, to: (charDataObj.chartData[index].value / 100) - 0.003)
内容的提问来源于stack exchange,提问作者FlatDog
相关产品推荐
相关产品推荐

