【问题标题】:swiftui, animation applied to parent effect child animationswiftui,动画应用于父效果子动画
【发布时间】:2021-01-05 15:49:07
【问题描述】:

RectangleView 有滑动动画,他的子 TextView 有旋转动画。我想当 Go!按下,TextView 永远旋转(线性)。但实际上子TextView与父TextView分离,旋转(线性)和滑动(线性),永远重复。

为什么将动画应用于父效果子动画?

struct AnimationTestView: View {
    @State private var go = false
    var body: some View {
        VStack {
            Button("Go!") {
                go.toggle()
            }
            if go {
                RectangleView()
                    .transition(.slide)
                    .animation(.easeInOut)
            }
        }.navigationTitle("Animation Test")
    }
}

struct RectangleView: View {
    var body: some View {
        Rectangle()
            .frame(width: 100, height: 100)
            .foregroundColor(.pink)
            .overlay(TextView())
    }
}

struct TextView: View {
    @State private var animationRotating: Bool = false
    let animation = Animation.linear(duration: 3.0).repeatForever(autoreverses: false)
    
    var body: some View {
        Text("Test")
            .foregroundColor(.blue)
            .rotationEffect(.degrees(animationRotating ? 360 : 0))
            .animation(animation)
            .onAppear { animationRotating = true }
            .onDisappear { animationRotating = false }
    }
}

【问题讨论】:

    标签: animation swiftui


    【解决方案1】:

    如果同时存在多个动画,通用解决方案(在大多数情况下)是为每个动画使用显式状态值。

    所以这里是一个更正的代码(用 Xcode 12.1 / iOS 14.1 测试,使用模拟器或设备,预览渲染一些过渡不正确)

    struct AnimationTestView: View {
        @State private var go = false
        var body: some View {
            VStack {
                Button("Go!") {
                    go.toggle()
                }
                    VStack {      // container needed for correct transition !!
                        if go {
                             RectangleView()
                                  .transition(.slide)
                        }
                    }.animation(.easeInOut, value: go)    // << here !!
            }.navigationTitle("Animation Test")
        }
    }
    
    struct RectangleView: View {
        var body: some View {
            Rectangle()
                .frame(width: 100, height: 100)
                .foregroundColor(.pink)
                .overlay(TextView())
        }
    }
    
    struct TextView: View {
        @State private var animationRotating: Bool = false
        let animation = Animation.linear(duration: 3.0).repeatForever(autoreverses: false)
        
        var body: some View {
            Text("Test")
                .foregroundColor(.blue)
                .rotationEffect(.degrees(animationRotating ? 360 : 0))
                .animation(animation, value: animationRotating)          // << here !!
                .onAppear { animationRotating = true }
                .onDisappear { animationRotating = false }
        }
    }
    

    【讨论】:

    • 现在 TextView 有了自己的状态。带有 TextView 的 RectangleView 在 3 秒内滑入屏幕,但在滑动时 TextView 的状态在一秒钟后发生了变化。现在可以看到 TextView 停止滑动了,一下子就到了目的地。我已经附加了上面的演示代码。
    • 这是不同的问题。一问一答。
    • 非常感谢。我花了很多时间寻找这个。
    猜你喜欢
    • 2021-05-23
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多