停止swiftUI动画并跳到目标值

停止swiftUI动画并跳到目标值,swiftui,Swiftui,我正在为我的应用程序中的一些场景设置剩余时间的动画。我有一个问题,当用户通过转到下一个场景中断此场景时,动画不会停止 此代码是正在发生的事情的简化版本: struct ContentView: View { @State private var remaining: Int = 40 @State private var sceneIndex: Int = 0 var body: some View { VStack(spacing: 30) {

我正在为我的应用程序中的一些场景设置剩余时间的动画。我有一个问题,当用户通过转到下一个场景中断此场景时,动画不会停止

此代码是正在发生的事情的简化版本:

struct ContentView: View {
    @State private var remaining: Int = 40
    @State private var sceneIndex: Int = 0

    var body: some View {
        VStack(spacing: 30) {
            Text("Remaining:")
            EmptyView().modifier(DoubleModifier(value: remaining))

            Button(action: {
                self.sceneIndex += 1
                if self.sceneIndex == 1 {
                    withAnimation(.linear(duration: 10)) {
                        self.remaining = 30
                    }
                } else {
                    withAnimation(.linear(duration: 0)) {
                        self.remaining = 30 // changing this to any other value will stop the animation
                    }
                }
            }) {
                Text("Go to next scene")
            }
        }
    }
}
发生的情况是,当用户单击倒计时时,动画将以10秒的持续时间初始化,并将剩余时间设置为40到30秒。现在,当用户单击“跳过”按钮时,动画应该停止并转到剩余的30秒。但是,它仍然显示40到30之间的动画(介于两者之间)

如果我在else语句中将self.remaining更改为30,则该值不会更新,因为它已设置为30,但在内部仍处于动画状态。 如果我将self.remaining更改为除30以外的任何其他有效值,例如self.remaining=29,动画确实会立即停止

我可以将else语句中的内容替换为:

withAnimation(.linear(duration: 0)) {
   self.remaining = 29

   DispatchQueue.main.async {
       self.remaining = 30
   }
}
它确实可以工作,但感觉非常混乱,在我的例子中,并不总是可以使用DispatchQueue.main.async

是否有其他更好的方法停止动画并跳到目标值


是否有可能在else语句中为self.remaining=30指定某种标识符,以便swiftUI知道该值实际上发生了变化,即使事实上没有发生变化,swiftUI也会停止动画?

不清楚从一个场景到另一个场景,一步一步地计划了什么逻辑,但现在所讨论的目标可以通过以下
主体实现:

var body: some View {
    VStack(spacing: 30) {
        Text("Remaining:")
        EmptyView().modifier(DoubleModifier(value: remaining)).id(sceneIndex)

        Button(action: {
            self.sceneIndex += 1
            withAnimation(.linear(duration: 10)) {
                self.remaining = 30
            }
        }) {
            Text("Go to next scene")
        }
    }
}

目前还不清楚从一个场景到另一个场景的步骤规划的逻辑是什么,但现在所讨论的目标可以通过以下
主体实现:

var body: some View {
    VStack(spacing: 30) {
        Text("Remaining:")
        EmptyView().modifier(DoubleModifier(value: remaining)).id(sceneIndex)

        Button(action: {
            self.sceneIndex += 1
            withAnimation(.linear(duration: 10)) {
                self.remaining = 30
            }
        }) {
            Text("Go to next scene")
        }
    }
}