【发布时间】:2020-04-12 11:30:26
【问题描述】:
我遇到了一个问题,即用户更新了一个部分中的一个项目,这会导致它被过滤并移动到另一个部分。发生这种情况时,行视图的内容并不总是得到更新。如图所示,当项目停留在同一部分时,它每次都会更新,而当它移动时,它只会每隔一次更新一次(尽管情况似乎并不总是如此)。它的行为就好像行视图正在被重用,并且提供给它的对象没有更新。我想知道是否有人遇到过这种情况并知道该怎么做。
这里是如何重新创建这个视图的代码。
在SceneDelegate.swift:
let contentView = ContentView().environmentObject(ItemStore())
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
然后在ContentView.swift:
import SwiftUI
struct ContentView: View {
@EnvironmentObject var itemStore: ItemStore
var body: some View {
NavigationView {
List {
Section(header: Text("Even")) {
ForEach(itemStore.itemsEven) { item in
ItemRowView(item: item) {
self.itemStore.increment(item: item)
}
}
}
Section(header: Text("Odd")) {
ForEach(itemStore.itemsOdd) { item in
ItemRowView(item: item) {
self.itemStore.increment(item: item)
}
}
}
Section(header: Text("All")) {
ForEach(itemStore.itemsAll) { item in
ItemRowView(item: item) {
self.itemStore.increment(item: item)
}
}
}
}
.listStyle(GroupedListStyle())
.navigationBarTitle("Items")
}
}
}
struct ItemRowView: View {
var item: Item
var onTap: () -> Void
var body: some View {
HStack {
Text(item.name)
Spacer()
Button(action: onTap) {
Text("\(item.count)")
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(ItemStore())
}
}
struct Item: Identifiable {
var id: String
var name: String
var count: Int
var isEven: Bool {
count % 2 == 0
}
}
class ItemStore: ObservableObject {
@Published var itemsEven: [Item]
@Published var itemsOdd: [Item]
@Published var itemsAll: [Item]
init() {
let even = [
Item(id: "0", name: "Star Wars", count: 0),
]
let odd: [Item] = []
itemsEven = even
itemsOdd = odd
itemsAll = even + odd
}
func increment(item: Item) {
printItems(title: "START")
var allItems = itemsAll
let index = allItems.firstIndex(where: { $0.id == item.id })!
let storedItem = allItems[index] // avoid captured value
allItems[index].count = storedItem.count + 1
print("DURING \(allItems) \(allItems[index].count) \(item.count + 1)")
allItems.sort { $0.count < $1.count }
itemsEven = []
itemsOdd = []
allItems.forEach { item in
if item.isEven {
itemsEven.append(item)
} else {
itemsOdd.append(item)
}
}
itemsAll = allItems
printItems(title: "END")
}
func printItems(title: String) {
print("\(title) ------------")
print("All \(itemsAll)")
print("Even \(itemsEven)")
print("Odd \(itemsOdd)")
print("------------------")
}
}
可能与Why is my SwiftUI List row not always updating internally重复
哦,第一次点击时左移的边距有点奇怪。
【问题讨论】:
-
如果不关心动画,可以在
List上加.id() -
啊,但我喜欢这个动画!
-
您找到解决方案了吗?再多的覆盖 Hashable、Equatable、Identifiable 似乎都无法为我解决这个问题。 ID 来自其他地方,所以我不能只选择一个新 ID,我想要动画。
标签: swiftui-list swiftui