【发布时间】:2020-08-12 15:17:51
【问题描述】:
我设法为ForEach 中显示的项目制作了一个漂亮的插入和删除动画(通过Row 上的.transition(...) 完成)。但遗憾的是,当我在观察到的数组中更新Item 的名称时,也会触发此动画。当然这是因为它实际上是一个新视图(您可以看到,因为调用了 Row 的 onAppear())。
众所周知,推荐使用酷炫动画管理列表的方法是 List,但我认为很多人希望避免使用标准 UI 或此元素带来的限制。
一个工作的 SwiftUI 附加了示例 sn-p(使用 Xcode 11.4 构建)
那么问题来了:
对于保持相同位置的更新项目,是否有一种巧妙的方法来抑制动画(或有另一种动画)?是否有一种很酷的可能性可以“重用”该行并对其进行更新?
或者答案是“让我们等待下一次 WWDC,看看 Apple 是否会修复它……”? ;-)
干杯,
奥兰多????
编辑
当您可以区分编辑/添加/删除(例如,通过手动用户操作)时,bonky frenks 的回答实际上是一种好方法。只要items 数组在后台更新(例如,通过来自您的视图模型中的核心数据的同步更新),您不知道这是否是更新。但也许在这种情况下,答案是在视图模型中手动实现插入/更新/删除案例。
struct ContentView: View {
@State var items: [Item] = [
Item(name: "Tim"),
Item(name: "Steve"),
Item(name: "Bill")
]
var body: some View {
NavigationView {
ScrollView {
VStack {
ForEach(items, id: \.self) { item in
Row(name: item.name)
}
}
}
.navigationBarItems(leading: AddButton, trailing: RenameButton)
}
}
private var AddButton: some View {
Button(action: {
self.items.insert(Item(name: "Jeff"), at: 0)
}) {
Text("Add")
}
}
private var RenameButton: some View {
Button(action: {
self.items[0].name = "Craigh"
}) {
Text("Rename first")
}
}
}
struct Row: View {
@State var name: String
var body: some View {
HStack {
Text(name)
Spacer()
}
.padding()
.animation(.spring())
.transition(.move(edge: .leading))
}
}
struct Item: Identifiable, Hashable {
let id: UUID
var name: String
init(id: UUID = UUID(), name: String) {
self.id = id
self.name = name
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
【问题讨论】:
标签: swift listview animation foreach swiftui