SwiftUI 圆形线宽更改​​停止修剪动画 [英] SwiftUI Circle line width change stops trim animation

查看:34
本文介绍了SwiftUI 圆形线宽更改​​停止修剪动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为圆的修剪属性设置动画.但是,如果动画正在运行并且我更改了线宽,则动画会立即(并且出乎意料地)结束.

I want to animate the trim attribute of a circle. However, if the animation is running and I change the line width, the animation finishes immediately (and unexpectedly).

有人知道我做错了什么吗?我相信这是一件非常简单的事情.

Does somebody have an idea what I am doing wrong? I'm sure it's a very simple thing.

感谢您的回答!

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()
    }
}

推荐答案

我不确定您是否可以直接做您希望做的事情.线条的描边使用 lineWidth,所以我不相信你可以用单独的时间间隔动画它.

I'm not sure you can directly do what you hope to do. The stroking of the line uses the lineWidth, so I don't believe you can animate it with a separate time interval.

您可以做的是随着时间的推移更改 lineWidth 以便在圆形动画运行和重新绘制圆形时,它将使用新值.

What you can do is change the lineWidth over time so that while the circle animation is running and redrawing the circle, it will use the new values.

考虑到这一点,我创建了函数 changeValueOverTime(value:newValue:duration) 来执行此操作:

With that in mind, I created the function changeValueOverTime(value:newValue:duration) to do this:

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()
            }
        }
    }
}

这篇关于SwiftUI 圆形线宽更改​​停止修剪动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆