swift 如何防止子视图中的动画出现在父视图中?

ukxgm1gy  于 5个月前  发布在  Swift
关注(0)|答案(1)|浏览(80)

我有一些代码,其中我有一个动画卡。
当我在另一个视图中使用视图时,动画对视图的其余部分有一个奇怪的效果。
如何将动画限制在子视图中?
这个错误发生在NavigationView内部。我需要为这个项目使用NavigationLink,所以没有NavigationView不是一个选项。
下面是代码,你可以自己看看:

struct ContentView: View {
    
    var body: some View {
        
        NavigationView {
            
            VStack {
                AnimatedCard()
                            
                Text("This is some text")
            }
        }
    }
}

struct AnimatedCard: View {
    
    @State private var animate = false

    
    var body: some View {
        VStack {
            ZStack {
                Circle()
                    .fill(.red)
                    .blur(radius: 10)
                    .offset(x:animate ? 10 : 130,y:animate ? 20 : 160)
                    .rotation3DEffect(.degrees(animate ? 30 : 0), axis: (x: animate ? 0 : 0.5, y: animate ? 0.2 : 0.7, z: animate ? 0.4 : 0))
                RoundedRectangle(cornerRadius: 10)
                    .fill(.pink)
                    .blur(radius: 20)
                    .offset(x: animate ? -120 : 10,y :animate ? -100 : 20)
                    .rotation3DEffect(.degrees(animate ? 80 : 20), axis: (x: animate ? 0.4 : 0, y: animate ? 0 : 0.1, z: animate ? 0 : 0.5))
                Rectangle()
                    .fill(.green)
                    .blur(radius: 30)
                    .offset(x: animate ? -60 : 20,y: animate ? 5 : 140)
                    .rotation3DEffect(.degrees(animate ? 20 : 50), axis: (x: animate ? 0 : 0, y: animate ? 0.4 : 0.2, z: animate ? 0.9 : 0.3))
                Capsule()
                    .fill(.mint)
                    .blur(radius: 40)
                    .offset(x: animate ? 60 : 0,y: animate ? -10 : 140)
                    .rotation3DEffect(.degrees(animate ? -30 : 0), axis: (x: animate ? 0.6 : 0.1, y: animate ? 0.2 : 0.3, z: animate ? 0.1 : 0.4))
                Circle()
                    .fill(.blue)
                    .blur(radius: 50)
                    .offset(x: animate ? 90 : -10,y:animate ? -90 : 40)
                    .rotation3DEffect(.degrees(animate ? 10 : 0), axis: (x: animate ? 0.4 : 0.6, y: animate ? 0.1 : 0, z: animate ? 0.6 : 0.4))
                RoundedRectangle(cornerRadius: 10)
                    .fill(.teal)
                    .blur(radius: 60)
                    .offset(x: animate ? -90 : 40,y:animate ? 90 : -20)
                    .rotation3DEffect(.degrees(animate ? -20 : 10), axis: (x: animate ? 0 : 0.2, y: animate ? 0 : 0 , z: animate ? 0.4 : 0))
                Capsule()
                    .fill(.yellow)
                    .blur(radius: 70)
                    .offset(x: animate ? 10 : 170 ,y:animate ? 0 : -150)
                    .opacity(0.4)
                    .rotation3DEffect(.degrees(animate ? 30 : 0), axis: (x: animate ? 0 : 0.1, y: animate ? 0.5 : 0.1, z: animate ? 0.2 : 0.6))
                
            }
            .frame(width: UIScreen.main.bounds.width - 60,height: UIScreen.main.bounds.height/2)
            .clipped()
            .cornerRadius(15)
            .shadow(color: Color.black.opacity(0.25), radius: 25, x: 0, y: 20)
            .onAppear() {
                withAnimation(.easeInOut(duration: 5).repeatForever(autoreverses: true)) {
                    animate.toggle()
                }
            }
            
        }
        .frame(width: UIScreen.main.bounds.width - 60,height: UIScreen.main.bounds.height/2)

    }
}

字符串

4c8rllxm

4c8rllxm1#

onAppear被过早调用。当我向.onAppear添加DispatchQueue时,这个问题得到了解决。
替换如下:

.onAppear {
                withAnimation(.easeInOut(duration: 5).repeatForever(autoreverses: true)) {
                    animate.toggle()
                }
            }

字符串
有了这个:

.onAppear {
                DispatchQueue.main.async {
                    withAnimation(.easeInOut(duration: 5).repeatForever(autoreverses: true)) {
                        animate.toggle()
                    }
                }
            }

相关问题