这是不起作用的基本示例:
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
的变化当然算作结构的变化,因此,状态之间的所有连续性都丢失了,所有交叉的东西都消失了。有人知道该怎么做吗?
答案 0 :(得分:0)
我想我已经将问题的动画部分简化了,但是不幸的是,我认为它不会保留相同的视图实例。我尝试将os.walk
放入变量中以查看是否可行,但是如果我正确理解SwiftUI,那并不意味着视图的同一实例将在两个地方共享。
我正在做的是在添加/删除绿色视图时添加一个过渡。这样,视图在消失之前将移动到其替换位置。
green
该解决方案快捷简便,并使用基于iPhone 6/7/8纵向屏幕尺寸的硬编码值
答案 1 :(得分:0)
您可以使用iOS 14 / macOS 10.16中引入的SwiftUI 2来做到这一点:
@Namespace private var animation
…
MyView.matchedGeometryEffect(id: "myID", in: animation)