专注于理解各种动画行为的基本概念,我对以编程方式为列表中的行的变化设置动画感兴趣。
我能够在以下示例中实现它:
struct First: View {
@State var items = ["One", "Two", "Three", "Four"]
var body: some View {
VStack {
List(items, id: \.self) { item in
Text(item)
}
Button("Hit me") {
withAnimation {
items.swapAt(2, 0)
}
}
}
}
}
正如您在点击按钮时所看到的,我们在单元格中收到了一个漂亮的交换动画。我们可以看到细胞实际上在移动,一个向上,另一个向下:
当我将列表代码更改为以下内容时:
List(items.indices, id: \.self) { index in
Text(items[index])
}
正如您所看到的,之前的动画不再起作用,而是我收到了文本更改动画:
有没有办法保留第一个(默认)交换动画?
谢谢。
最佳答案
这是一个身份问题。 SwiftUI 通过 View 元素的标识来跟踪 View 元素,并且只有当单个元素的标识保持相同时,它才能在状态之间进行动画处理。
在第一个代码中,List id 的类型为String
,字符串改变位置但保持相同的 id。
在第二个代码中,List id 的类型为 Index,但交换索引时不会更改,只会更改该索引处的相对字符串。
因此,在结果中,1. 根据字符串 id 对位置进行动画处理,2. 根据索引 id 对字符串进行动画处理。
但是你可以明确告诉 SwiftUI 使用哪个 id,也在第二个代码中,如下所示:
List(items.indices, id: \.self) { index in
Text(items[index]).id(items[index]) // Here
}
关于animation - 使用 SwiftUI 动画列表中的行更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76226338/