ors*_*aef 9 foreach animation listview swift swiftui
我设法为 a 中显示的项目制作了一个很好的插入和删除动画ForEach(通过.transition(...)on完成Row)。但遗憾的是,当我只是更新Item观察到的数组中的名称时,也会触发此动画。当然这是因为它实际上是一个新视图(您可以看到,因为调用了onAppear()of Row)。
众所周知,推荐的管理带有酷动画的列表的方法是,List但我认为许多人希望避免标准 UI 或此元素带来的限制。
附加了一个有效的 SwiftUI示例片段(使用 Xcode 11.4 构建)
所以,问题:
是否有一种聪明的方法可以为保持相同位置的更新项目抑制动画(或有另一个)?是否有一种很酷的可能性来“重用”该行并对其进行更新?
或者答案是“让我们等待下一个 WWDC,让我们看看 Apple 是否会修复它......”?;-)
干杯,
奥兰多
编辑
当您可以区分编辑/添加/删除(例如,通过手动用户操作)时,笨拙的前辈答案实际上是一种很好的方法。一旦items数组在后台更新(例如通过来自视图模型中的 Core Data 的同步更新),您不知道这是否是更新。但也许在这种情况下,答案是在视图模型中手动实现插入/更新/删除情况。
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()
}
}
Run Code Online (Sandbox Code Playgroud)
bon*_*onk 12
幸运的是,这实际上很容易做到。只需删除.animation(.spring())您的行,并将所有更改包装在withAnimation(.spring()) { ... }.
所以添加按钮将如下所示:
private var AddButton: some View {
Button(action: {
withAnimation(.spring()) {
self.items.insert(Item(name: "Jeff"), at: 0)
}
}) {
Text("Add")
}
}
Run Code Online (Sandbox Code Playgroud)
你的行将如下所示:
struct Row: View {
@State var name: String
var body: some View {
HStack {
Text(name)
Spacer()
}
.padding()
.transition(.move(edge: .leading))
}
}
Run Code Online (Sandbox Code Playgroud)