SwiftUI - 如何更改视图的层级位置?

4
这是一个不起作用的基本示例:
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中的展开状态中,这样它们就会垂直展开并全部可见。从ZStack切换到VStack当然算作是对结构的更改,因此所有状态之间的连续性都会丢失,一切都只是交叉淡化。有人知道该怎么做吗?
2个回答

1
你可以使用在iOS 14 / macOS 10.16中引入的SwiftUI 2来实现这个功能:
@Namespace private var animation
…
MyView.matchedGeometryEffect(id: "myID", in: animation)

-1

我认为我已经掌握了你问题的动画部分,但不幸的是,我不认为它会保持相同的视图实例。 我试着将green放入变量中,看看是否有效,但如果我正确理解SwiftUI,则这并不意味着相同的视图实例将在两个地方共享。

我所做的是在添加/删除绿色视图时添加了一个过渡效果。这样,在消失之前,视图就会移动到其替换位置。

struct Test : View {
    @State var swapped = false
    let green = Color.green

    var body: some View {
        HStack {
            if swapped {
                green
                    .transition(.offset(CGSize(width: 200, height: 0)))
                    .animation(.basic())
            }
            Color.blue.animation(.basic()).tapAction {
                withAnimation { self.swapped.toggle() }
            }
            if !swapped {
                green.transition(.offset(CGSize(width: -200, height: 0)))
                .animation(.basic())
            }
        }
    }
}

这个解决方案是快速而粗略的,使用基于iPhone 6/7/8竖屏尺寸的硬编码值。


这不是问题的解决方案,它以非常硬编码的方式覆盖了SwiftUI。他想要一种告诉SwiftUI去做的方法。 - Gusutafu
这并不能帮助从ZStack到VStack的转换。显然,他正在寻找一种使用布局来定位和动画视图的方法。 - B Roy Dawson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接