【问题标题】:Nested transitions / animations in SwiftUISwiftUI 中的嵌套过渡/动画
【发布时间】:2021-01-12 22:24:43
【问题描述】:

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

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

工作,但可能不必要的复杂:

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()
    }
}

【问题讨论】:

    标签: swift xcode animation swiftui transition


    【解决方案1】:

    虽然它可能比这个简单的答案更棘手,但您可以将combine 转换在一起,以便它们无缝地生效:

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

    在最佳情况下,您不应该需要那些AnyTransitions:

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

    但它有时会导致 Xcode 错误,这可能会或可能不会提供任何关于 Xcode 与您的代码存在的真正问题的线索。

    (可选)您可能需要定义您的转换是否应仅在 removalinsertion 上生效,或者在每个 removalinsertion 上要求不同的转换:

    .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
    

    【讨论】:

    • 这是个好主意,可惜它没有解决。它。您的组合建议将动画组合应用于堆栈中的所有元素。实际目标是移动整个堆栈,但只更改堆栈中一个元素的不透明度。
    • 我现在根据您的建议找到了一种方法,但我怀疑这是实现这个想法的好方法......有什么想法吗?我想知道我是否真的是唯一一个试图存档这样一个动画的人,嗯。找不到更多关于此的文档。
    • 我发现转换有点棘手,所以我不能说更多,因为在我尝试之前我不确定。我不确定您尝试了什么,但我最好的猜测是您应该尝试计算单元格应该行进的距离,以到达屏幕顶部,并使用 AnyTransition.offset() + 计算值。否则,您可能需要进行自定义转换...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 2020-03-25
    • 2013-05-16
    • 1970-01-01
    相关资源
    最近更新 更多