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

Posted

技术标签:

【中文标题】swiftui,动画应用于父效果子动画【英文标题】:swiftui, animation applied to parent effect child animation 【发布时间】: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 
    

【问题讨论】:

【参考方案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 停止滑动了,一下子就到了目的地。我已经附加了上面的演示代码。 这是不同的问题。一问一答。 好的,我来新Q。***.com/questions/65614683/… 非常感谢。我花了很多时间寻找这个。

以上是关于swiftui,动画应用于父效果子动画的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中禁用子视图上的特定状态更改动画

SwiftUI 动画如何与子视图隔离?

SwiftUI如何模拟视图发光增大的动画效果

SwiftUI如何模拟视图发光增大的动画效果

SwiftUI中应用Hero动画(Hero Animation)时一些需要填的坑

SwiftUI中应用Hero动画(Hero Animation)时一些需要填的坑