SwiftUI:在 NavigationView 中破坏了显式动画?

Arm*_*man 17 animation swiftui

当我在 NavigationView 中放置显式动画时,作为不良副作用,它会为 NavigationView 内容的初始布局设置动画。无限动画会变得特别糟糕。有没有办法禁用这种副作用?

示例:下图应该是全屏蓝色背景上的红色动画加载器。相反,我得到了缩放蓝色背景的无限循环:

在此处输入图片说明

import SwiftUI

struct EscapingAnimationTest: View {
    var body: some View {
        NavigationView {
            VStack {
                Spacer()
                EscapingAnimationTest_Inner()
                Spacer()
            }
            .backgroundFill(Color.blue)
        }
    }
}

struct EscapingAnimationTest_Inner: View {
    @State var degrees: CGFloat = 0
    
    var body: some View {
        Circle()
            .trim(from: 0.0, to: 0.3)
            .stroke(Color.red, lineWidth: 5)
            .rotationEffect(Angle(degrees: degrees))
            .onAppear() {
                withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) {
                    degrees = 360
                }
            }
    }
}

struct EscapingAnimationTest_Previews: PreviewProvider {
    static var previews: some View {
        EscapingAnimationTest()
    }
}
Run Code Online (Sandbox Code Playgroud)

Asp*_*eri 23

这里是固定部分。使用 Xcode 12 / iOS 14 测试。

演示

struct EscapingAnimationTest_Inner: View {
    @State var degrees: CGFloat = 0
    
    var body: some View {
        Circle()
            .trim(from: 0.0, to: 0.3)
            .stroke(Color.red, lineWidth: 5)
            .rotationEffect(Angle(degrees: Double(degrees)))
            .animation(Animation.linear(duration: 1).repeatForever(autoreverses: false), value: degrees)
            .onAppear() {
                    DispatchQueue.main.async {
                    degrees = 360
                    }
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:同样将使用withAnimation

.onAppear() {
    DispatchQueue.main.async {
        withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) {
           degrees = 360
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 您知道为什么将“withAnimation”包装在“DispatchQueue.main.async {}”中可以解决该问题吗? (6认同)
  • 伙计,SwiftUI 还有很长的路要走。伤心。 (4认同)
  • 我的错,我错过了 .animation() 方法中的最终“值”参数。您的两个解决方案都有效,谢谢!顺便说一句,您知道为什么在我的原始代码中显式动画启动 NavigationView 动画吗?从概念上讲不应该。这是一个错误吗? (3认同)
  • 我遇到了同样的问题,包装在 DispatchQueue.main.async 中对我有帮助。但我真的很想知道它为什么以及如何工作:) (3认同)