首页 > 解决方案 > SwiftUI - 如何更改视图的层次位置?

问题描述

这是一个不起作用的基本示例:

import SwiftUI

struct Test : View {
    @State var swapped = false

    var body: some View {
        if swapped { Color.green }
        Color.blue.tapAction {
            withAnimation { self.swapped.toggle() }
        }
        if !swapped { Color.green }
    }
}

SwiftUI 无法弄清楚我认为第一个Color.green和第二个Color.green视图是同一个视图,所以当然动画只是将其中一个淡出,同时在新位置淡入另一个。我正在寻找向 SwiftUI 指示这些是相同视图并将其动画化到新位置的方法。我非常兴奋地发现了这个.id()修饰符,因为我相信它会给我想要的效果:

import SwiftUI

struct Test : View {
    @State var swapped = false

    var body: some View {
        if swapped { Color.green.id("green") }
        Color.blue.tapAction {
            withAnimation { self.swapped.toggle() }
        }
        if !swapped { Color.green.id("green") }
    }
}

不幸的是,这也不起作用。我对 SwiftUI 感到难以置信的兴奋,但在我看来,在保持视图标识的同时更改视图层次结构的能力非常重要。促使我考虑这一点的实际用例是,我有一些视图,我正在尝试为其创建粉丝动画。最简单的方法是让项目处于ZStack一种状态,使它们都在彼此之上,然后让它们处于VStack扇出状态,这样它们就可以垂直展开并且全部可见。从 a 更改为ZStackaVStack当然算作结构的更改,因此状态之间的所有连续性都丢失了,一切都只是交叉淡入淡出。有谁知道该怎么做?

标签: animationstructureidentityswiftuiview-hierarchy

解决方案


您可以使用 iOS 14 / macOS 10.16 中引入的 SwiftUI 2 来做到这一点:

@Namespace private var animation
…
MyView.matchedGeometryEffect(id: "myID", in: animation)

推荐阅读