SwiftUI中的嵌套过渡/动画

时间:2020-09-26 23:45:54

标签: swift xcode animation swiftui transition

目标是在另一个视图的顶部创建一个视图,该视图具有元素并在移至屏幕顶部时更改颜色。因此,我们有一个变量/状态触发一个动画,其中两个视图都具有子过渡/动画。 问题是:在动画/过渡中的某个点上没有运动或没有颜色过渡,因为添加过渡会以某种方式覆盖堆栈中元素的所有单个过渡。

编辑:由于简单起见,我重新安排了代码,避免了所描述的行为。但这似乎是一个非常糟糕的解决方案(如果要重复很多代码,……)。有人知道如何以更紧凑/更高级的方式编写以下工作示例吗?

有效,但可能不必要的复杂操作:

struct ContentView: View {
    @State var signUpLoginView_active: Bool = true
    var body: some View {
        ZStack{
            Color.orange
            if signUpLoginView_active {
                ZStack {
                    Color.white
                }
                .transition(.move(edge: .top))
                .zIndex(1)
            }
            if signUpLoginView_active {
                ZStack {
                    Color.red
                }
                .transition(AnyTransition.move(edge: .top).combined(with: AnyTransition.opacity))
                .zIndex(2)
            }
            Button("test"){
                withAnimation(.easeInOut(duration: 2)){
                    signUpLoginView_active.toggle()
                }
            }.zIndex(3)
        }.ignoresSafeArea()
    }
}

我的简化方法(无法正常工作):

struct ContentView: View {
    @State var signUpLoginView_active: Bool = true
    var body: some View {
        ZStack{
            Color.orange
            if signUpLoginView_active {
                ZStack {
                    Color.white
                    Color.red.opacity(signUpLoginView_active ? 1 : 0)
                }
                .transition(AnyTransition.move(edge: .top))
            }
            Button("test"){
                withAnimation(.easeInOut){
                    signUpLoginView_active.toggle()
                }
            }
        }.ignoresSafeArea()
    }
}

1 个答案:

答案 0 :(得分:0)

尽管它可能比这个简单的答案更为棘手,但您可以combine一起进行过渡,以使它们无缝生效:

.transition(AnyTransition.move(edge: .top)
            .combined(with: AnyTransition.scale))

在最佳情况下,您不需要这些AnyTransition

.transition(.move(edge: .top)
            .combined(with: .scale))

但是它有时会导致Xcode错误,这可能会或可能不会提供有关Xcode与您的代码有关的实际问题的任何线索。

(可选)您可能需要定义您的转换是否只在removalinsertion上生效,还是要求在removalinsertion的每一个上进行不同的转换:< / p>

.transition(AnyTransition.asymmetric(insertion: AnyTransition.move(edge: .top),
                                 removal: AnyTransition.move(edge: .bottom))
            .combined(with: AnyTransition.asymmetric(insertion: .scale,
                                                     removal: .identity)))
                                        // `.identity` means no transition