SwiftUI 在动画期间意外的位置变化

问题描述

我在 SwiftUI 中制作了一个简单的动画,它会在启动应用程序时直接重复。 然而,当运行代码时,动画圆圈会移动到左上角,然后在执行动画的其余部分时返回到其正常位置。这个左上角的动画不是预期的,也没有写在我的代码中。

示例代码

struct Loader: View {
    
    @State var animateFirst = false

    @State var animationFirst = Animation.easeInOut(duration: 3).repeatForever()
    var body: some View {
        ZStack {
            Circle().trim(from: 0,to: 1).stroke(ColorsPalette.Primary,style: strokeStyle(linewidth: 3,lineCap: .round)).rotation3DEffect(
                .degrees(self.animateFirst ? 360 : -360),axis: (x: 1,y: 0,z: 0),anchor: .center).frame(width: 200,height: 200,alignment: .center).animation(animationFirst).onAppear {
                self.animateFirst.toggle()
            }
        }
    }
    
}

然后在这样的视图中显示它:

struct LoaderViewer: View {
    
    var body: some View {
        vstack {
            Loader().frame(width: 200,height: 200)
        }
}

解决方法

我不知道为什么会发生这种情况,但我有一个模糊的想法。 因为动画在视图以宽度和高度完全渲染之前开始,所以视图从左上角开始。动画采用动画中的起始位置并更改为其正常位置,并使用给定的动画不断重复此部分。这会导致这种意外行为。

我认为这是一个错误,但根据上述理论,我现在已经创建了一个解决方法。在我们放置加载器的视图中,我们必须等到父视图完全渲染后再添加动画视图(加载器视图),我们可以这样做:

struct LoaderViewer: View {

    @State showLoader = false

    var body: some View {
        VStack {
            if showLoader {
                Loader().frame(width: 200,height: 200)
            }
        }.onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) {
                showLoader = true
            }
        }
    }
}

相关问答

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