4

我一直在测试基于SwiftUI-labs的转换是如何工作的,但我发现转换不应该都以相同的方式实现。基于上一篇文章:

请注意,从 XCode 11.2 开始,过渡不再适用于隐式动画

事情是,我发现了一些奇怪的东西。使用隐式动画或将动画与其关联时,某些过渡效果很好。那么,应该使用什么动画呢?这得看情况。什么?我不知道。我希望任何人都可以帮助我解释这一切。

在下面的测试中,我创建了 5 个视图,每个视图都与不同的转换相关联:.opacity.scale.move.slidecombined(.opacity.move)。以下是我的发现:

注意:我使用的是 XCODE 11.4 和模拟器!

使用隐式动画的过渡

只有.move.slide转换工作正常(删除和插入)。

在此处输入图像描述

使用显式动画的过渡

移除和插入动画适用于所有过渡。

在此处输入图像描述

将动画与每个过渡相关联

只有.scale.opacity转换工作正常(删除和插入)。

在此处输入图像描述

从我的角度来看,没有实现转换的标准方法会使事情变得复杂,而且在组合转换时(.combined)。

我错过了一些关于实施的东西吗?这是我的代码:

struct TestAnimation: View {
    @State var show : Bool = true
    var colors : [Color] = [.orange, .yellow, .green, .blue, .pink]

    var body: some View {
        VStack(alignment: .leading) {
            Spacer()

            Color.purple
                .frame(height: 100)
                .overlay(
                    Text("Tap Me!").foregroundColor(.white))
                .onTapGesture {
                    // (#1) implicit animation
                    self.show.toggle()

                    // (#2) explicit animation
                    /*withAnimation(Animation.easeInOut(duration: 1)) {
                        self.show.toggle()
                    }*/

                    // (#3) associate an animation with a transition
                    //self.show.toggle()
            }

            HStack {
                if show {
                    Rectangle()
                        .fill(colors[0])
                        .frame(width: 70, height: 100)
                        .overlay(Text("opacity"))
                        .transition(AnyTransition.opacity) // (#1) - doesn't animate, only removes/inserts the view
                        .animation(.easeInOut(duration: 1)) // (#1) 
                        //.transition(AnyTransition.opacity) // (#2) - only animates the removal, not the insertion
                        //.transition(AnyTransition.opacity.animation(.easeInOut(duration: 1))) // (#3) - animates removal and insertion

                    Rectangle()
                        .fill(colors[1])
                        .frame(width: 70, height: 100)
                        .overlay(Text("scale"))
                        .transition(AnyTransition.scale) // (#1) - doesn't animate, only removes/inserts the view
                        .animation(.easeInOut(duration: 1)) // (#1) 
                        //.transition(AnyTransition.scale) // (#2) - only animates the removal, not the insertion
                        //.transition(AnyTransition.scale.animation(.easeInOut(duration: 1))) // (#3) - animates removal and insertion

                    Rectangle()
                        .fill(colors[2])
                        .frame(width: 70, height: 100)
                        .overlay(Text("move"))
                        .transition(AnyTransition.move(edge: .bottom)) // (#1) - animates removal and insertion
                        .animation(.easeInOut(duration: 1)) // (#1) 
                        //.transition(AnyTransition.move(edge: .bottom)) // (#2) - only animates the removal, not the insertion
                        //.transition(AnyTransition.move(edge: .bottom).animation(.easeInOut(duration: 1))) // (#3) - doesn't animate, only removes/inserts the view

                    Rectangle()
                        .fill(colors[3])
                        .frame(width: 70, height: 100)
                        .overlay(Text("slide"))
                        .transition(AnyTransition.slide) // (#1) - animates removal and insertion
                        .animation(.easeInOut(duration: 1)) // (#1) 
                        //.transition(AnyTransition.slide) // (#2) - only animates the removal, not the insertion
                        //.transition(AnyTransition.slide.animation(.easeInOut(duration: 1))) // (#3) - doesn't animate, only removes/inserts the view

                    Rectangle()
                    .fill(colors[4])
                    .frame(width: 70, height: 100)
                    .overlay(Text("op&mv"))
                    .transition(AnyTransition.opacity.combined(with: .move(edge: .bottom))) // (#1) - doesn't animate, only removes/inserts the view
                    .animation(.easeInOut(duration: 1)) // (#1) 
                    //.transition(AnyTransition.opacity.combined(with: .move(edge: .bottom))) // (#2) - only animates removal, not the insertion
                        //.transition(AnyTransition.opacity.combined(with: .move(edge: .bottom)).animation(.easeInOut(duration: 1))) // (#3) - animates removal (it's not smooth), and only animates opacity on insertion
                }
            }
            .frame(height: 100)
            .padding(7)
                .border(Color.gray)
        }
    }

}
4

0 回答 0