我想为圆的修剪属性设置动画。但是,如果动画正在运行并且我更改了线宽,则动画会立即(且意外地)结束。
有人知道我在做什么错吗?我敢肯定这是一件非常简单的事情。
感谢您的回答!
import SwiftUI
struct ContentView: View {
@State var progress: Double = 0.01
@State var lineWidth: CGFloat = 20
var body: some View {
VStack{
CircleView(progress: progress, lineWidth: lineWidth)
.foregroundColor(.orange)
.onAppear{
withAnimation(.linear(duration: 20)){
progress = 1
}
}
.padding()
Button(action: {
withAnimation{
lineWidth = 40
}
}, label: {Text("Change Line Width")})
}
}
}
struct CircleView: View {
var progress: Double
var lineWidth: CGFloat
var body: some View {
Circle()
.trim(from: 0, to: CGFloat(progress))
.stroke(style: StrokeStyle(lineWidth: lineWidth, lineCap: .round, lineJoin: .round))
.padding()
}
}
答案 0 :(得分:1)
只需删除第二个动画就可以了。经过Xcode 12 / iOS 14的测试
Button(action: {
lineWidth = 40 // << no animation here !!
}, label: {Text("Change Line Width")})
答案 1 :(得分:1)
我不确定您可以直接完成您希望做的事情。该行的描边使用lineWidth
,因此我认为您不能使用单独的时间间隔对其进行动画处理。
您可以做的是随着时间的推移更改lineWidth
,以便在运行圆动画并重画圆时,它将使用新值。
牢记这一点,我创建了函数changeValueOverTime(value:newValue:duration)
来做到这一点:
struct ContentView: View {
@State var progress: Double = 0.01
@State var lineWidth: CGFloat = 20
var body: some View {
VStack{
CircleView(progress: progress, lineWidth: $lineWidth)
.foregroundColor(.orange)
.onAppear{
withAnimation(.linear(duration: 20)){
progress = 1
}
}
.padding()
Button(action: {
changeValueOverTime(value: $lineWidth, newValue: 40, duration: 0.5)
}, label: {Text("Change Line Width")})
}
}
func changeValueOverTime(value: Binding<CGFloat>, newValue: CGFloat, duration: Double) {
let timeIncrements = 0.02
let steps = Int(duration / timeIncrements)
var count = 0
let increment = (newValue - value.wrappedValue) / CGFloat(steps)
Timer.scheduledTimer(withTimeInterval: timeIncrements, repeats: true) { timer in
value.wrappedValue += increment
count += 1
if count == steps {
timer.invalidate()
}
}
}
}