SwiftUI:导航视图中的动画

问题描述

我正在尝试在 SwiftUI 中创建一个简单的动画。它基本上是一个改变其框架的矩形,同时保持在父视图的中心。

struct ContentView: View {
    var body: some View {
        NavigationView {
            vstack {
                Text("Text")
                ZStack {
                    Color.blue
                    SquareAnimation().frame(width: 200,height: 200,alignment: .center)
                }
                Text("Text")
            }
        }
    }
}

struct SquareAnimation: View {
    var currentRect = CGRect(x: 0,y: 0,width: 50,height: 50)
    var finalRect = CGRect(x: 0,width: 100,height: 100)
    
    private let animation = Animation.easeInOut(duration: 1).repeatForever(autoreverses: true)
    
    @State var animate = false
    
    var body: some View {
        ZStack() {
            Color.clear
            Rectangle()
                .frame(width: animate ? finalRect.width: currentRect.width,height: animate ? finalRect.height: currentRect.height,alignment: .center)
                .animation(animation,value: animate)
                .onAppear() {
                    animate = true
                }
        }
        
    }
} 

问题是,如果使用 NavigationView,黑色矩形不会留在中心。
我也使用了无用的显式动画。为什么 NavigationView 会影响矩形动画? 谢谢!

解决方法

当视图框架在 NavigationView 中为零时,onAppear 被过早调用,因此应用动画从零变为值。

这是有效的解决方法。使用 Xcode 12.4 / iOS 14.4 测试

var body: some View {
    ZStack() {
        Color.clear
        Rectangle()
            .frame(width: animate ? finalRect.width: currentRect.width,height: animate ? finalRect.height: currentRect.height,alignment: .center)
            .animation(animation,value: animate)
            .onAppear {
                DispatchQueue.main.async {   
                   // << postpone till end of views construction !!
                    animate = true
                }
            }
    }
}

注意:几乎所有why问题都只能由 Apple 回答......也许这是一个错误,也许是实现细节。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...