введите описание изображения здесь
Я совершенно новичок в программировании для устройств Apple и начал изучать SwiftUI. Может кто-нибудь, пожалуйста, помогите мне с отображением значения p ie за пределами p ie. Как вы можете видеть на первом изображении, все 3 значения накладываются друг на друга, но я хочу что-то вроде второго изображения.
Точное место, где я накладываю текст, отмечено комментарием, как показано ниже:
.overlay(
Text(String(value)) // ****** This is the place where value is overlayed
)
А весь код ниже:
import SwiftUI
public struct PieChartCell : View {
@State private var show:Bool = false
var rect: CGRect
var radius: CGFloat {
return min(rect.width, rect.height)/2
}
var value: Double
var startDeg: Double
var endDeg: Double
var path: Path {
var path = Path()
path.addArc(center:rect.mid , radius:self.radius, startAngle: Angle(degrees: self.startDeg), endAngle: Angle(degrees: self.endDeg), clockwise: false)
path.addLine(to: rect.mid)
path.closeSubpath()
return path
}
var index: Int
var foregroundColor:Color
public var body: some View {
path
.fill()
.foregroundColor(self.foregroundColor)
.overlay(
Text(String(value)) // ****** This is the place where value is overlayed
)
.scaleEffect(self.show ? 1 : 0)
.animation(Animation.spring().delay(Double(self.index) * 0.04))
.onAppear(){
self.show = true
}
}
}
extension CGRect {
var mid: CGPoint {
return CGPoint(x:self.midX, y: self.midY)
}
}
struct PieSlice: Identifiable {
var id = UUID()
var startDeg: Double
var endDeg: Double
var value: Double
var foregroundColor: Color
}
public struct Pie : View {
var data: [QuestionType: Double]
var slices: [PieSlice] {
var tempSlices:[PieSlice] = []
var lastEndDeg:Double = 0
let maxValue = data.values.reduce(0, +)
for slice in data.keys {
let normalized:Double = Double(data[slice]!)/Double(maxValue)
let startDeg = lastEndDeg
let endDeg = lastEndDeg + (normalized * 360)
lastEndDeg = endDeg
tempSlices.append(PieSlice(startDeg: startDeg, endDeg: endDeg, value: data[slice]!, foregroundColor: slice.getColor()))
}
return tempSlices
}
public var body: some View {
GeometryReader { geometry in
ZStack{
ForEach(0..<self.slices.count){ i in
PieChartCell(
rect: geometry.frame(in: .local),
value: self.slices[i].value,
startDeg: self.slices[i].startDeg,
endDeg: self.slices[i].endDeg,
index: i,
foregroundColor: self.slices[i].foregroundColor)
}
}
}
}
}
public struct PieChart : View {
public var data: [QuestionType: Double]
public var title: String
public var legend: String
public var style: ChartStyle
public var formSize:CGSize
public var dropShadow: Bool
public init(data: [QuestionType: Double], title: String, legend: String, style: ChartStyle = Styles.pieChartStyleOne, form: CGSize? = ChartForm.medium, dropShadow: Bool? = true ){
self.data = data
self.title = title
self.legend = legend
self.style = style
self.formSize = form!
self.dropShadow = dropShadow!
}
public var body: some View {
ZStack{
Rectangle()
.fill(self.style.backgroundColor)
.cornerRadius(20)
.shadow(color: Color.gray, radius: self.dropShadow ? 12 : 0)
VStack(alignment: .leading){
HStack{
Text(self.title)
.font(.headline)
.foregroundColor(self.style.textColor)
Spacer()
Image(systemName: "chart.pie.fill")
.imageScale(.large)
.foregroundColor(self.style.legendTextColor)
}.padding()
Pie(data: data)
LegendView()
}
}.frame(width: self.formSize.width, height: self.formSize.height)
}
}
struct Legend: Hashable {
let color: Color
let label: String
}
struct LegendView: View {
private let legends: [Legend] = [
Legend(color: Color.green, label: "Correct"),
Legend(color: Color.red, label: "Incorrect"),
Legend(color: Color.blue, label: "Unattempted")
]
var body: some View {
HStack(alignment: .center) {
ForEach(legends, id: \.self) { legend in
HStack(alignment: .center) {
Circle()
.fill(legend.color)
.frame(width: 16, height: 16)
Text(legend.label)
.font(.subheadline)
.lineLimit(nil)
}
}
}
}
}
#if DEBUG
struct PieChart_Previews : PreviewProvider {
static var previews: some View {
PieChart(data:[
QuestionType.Correct: 10,
QuestionType.Incorrect: 25,
QuestionType.Unattempted: 15
], title: "Title", legend: "Legend")
}
}
#endif
А вот ContentView
import SwiftUI
struct ContentView: View {
@State var tabIndex:Int = 0
var body: some View {
TabView(selection: $tabIndex) {
PieCharts().tabItem { Group{
Image(systemName: "chart.pie")
Text("Pie charts")
}}.tag(2)
}
}
}
struct PieCharts:View {
var body: some View {
VStack{
PieChart(data: [
QuestionType.Correct: 10,
QuestionType.Incorrect: 5,
QuestionType.Unattempted: 25
], title: "Title", legend: "legend")
}
}
}