Я пытаюсь анимировать действие прокрутки этого представления. Цель этого представления - показать уровень запаса, пока у меня есть рабочие кнопки, изменение цвета (анимированное) и ar c, который изменяется в зависимости от количества элементов.
Я хочу анимировать второй Ar c в ZStack, когда я изменяю значение numberOfItems.
Видео текущей операции
Мой текущий код:
func colorStatus(stockNumber:Int) -> Color {
var stockColor: Color = .red
if stockNumber >= 10 {
stockColor = .green
} else if stockNumber >= 5 {
stockColor = .yellow
} else if stockNumber > 0 {
stockColor = .red
} else {
stockColor = .gray
}
return stockColor
}
struct Arc: Shape {
var startAngle: Angle
var endAngle: Angle
var anticlockwise: Bool
func path(in rect: CGRect) -> Path {
var path = Path()
path.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: rect.width / 2, startAngle: startAngle, endAngle: endAngle, clockwise: anticlockwise)
return path
}
}
let sfSize: CGFloat = 38
let minusImage: some View = Image(systemName: "minus.circle").font(.system(size: sfSize))
let plusImage: some View = Image(systemName: "plus.circle").font(.system(size: sfSize))
struct ContentView: View {
@State var numberOfItems: Int = 3
func circleRatio (sNum:Int) -> Double {
var r = Float(sNum) / 20
if r > 1 {
r = 1
}
let cRatio = 360 * 3 / 4 * Double(r) - (360-135)
return cRatio
}
var body: some View {
VStack {
Button (action: {
print("successful '+' tap")
self.numberOfItems += 1
})
{
plusImage
}.padding(.bottom, 25)
ZStack {
Arc(startAngle: .degrees(135), endAngle: .degrees(45), anticlockwise: false)
.stroke(style: StrokeStyle(lineWidth: 28, lineCap: .round))
.frame(width: 150, height: 150)
.foregroundColor(colorStatus(stockNumber: numberOfItems)).opacity(0.1).animation(.easeIn(duration: 0.25))
Arc(startAngle: .degrees(135), endAngle: .degrees(circleRatio(sNum: numberOfItems)), anticlockwise: false)
.stroke(colorStatus(stockNumber: numberOfItems), style: StrokeStyle(lineWidth: 30, lineCap: .round)).animation(.easeIn(duration: 0.25))
.frame(width: 150, height: 150)
//.animation(.spring(response: 5.0))
VStack {
Text("\(numberOfItems)").font(.largeTitle).padding()
Text("Units")
.foregroundColor(.secondary)
.font(.headline)
}
}
if self.numberOfItems > 0 {
Button(action: {
print("successful '-' tap")
if self.numberOfItems > 0 { self.numberOfItems -= 1}
else {print("Invalid - can't be < 0")}
}){
minusImage
}
} else { minusImage.font(.largeTitle).foregroundColor(.secondary) }
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().colorScheme(.light)
}
}
}