swiftui,动画应用于父效果子动画

foo*_*ear 4 animation swiftui

RectangleView有滑动动画,他的子TextView有旋转动画。我想当 Go! 时, RectangleView 及其子组件(TextView)作为一个整体滑入屏幕(easeInOut)!按下,并且 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 }
    }
}
Run Code Online (Sandbox Code Playgroud)

Asp*_*eri 7

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

所以这里是一个更正的代码(使用 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 }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这是不同的问题。一问一答。 (2认同)