SwiftUI 列表在@ObservedObject 更新时冻结
SwiftUI List freezes on @ObservedObject update
我有一个列表,它会在快结束时自动获取更多数据:
struct AdCardListView: View {
@ObservedObject var model: AdListViewModel = AdListViewModel()
var body: some View {
List { ForEach(self.model.adArray.enumerated().map({ [=10=] }), id: \.element.id) { index, ad in
AdCardView(ad: ad)
.onAppear {
DispatchQueue.main.async {
let count = self.model.adArray.count
if index >= count - 5 { //5 Views to the end, start loading more.
self.model.fetch(count: count)
}
}
}
}
}
}
}
模特长得像:
final class AdListViewModel: ObservableObject {
@Published var adArray = [Ad]()
...
func fetch(count: Int = 0) {
...
DispatchQueue.main.async {
self.adArray.append(contentsOf: newAds) //<-- problem here
}
...
}
我的问题:每次@Published/@ObservedObject 修改时滚动列表时我都有一点冻结。另外,我发现 List 重新计算了所有可见视图的主体 + 上面和下面的几个视图。
但我无法确定是什么导致滚动挂起并修复它(也许冻结是转移到等于(滚动速度*渲染时间)的距离?
为什么 SwiftUI 在现有视图上重新计算主体?他们没有改变!
你能帮帮我吗?
recreation body 不应该issue.I怀疑性能问题与List的更新动画有关
您是否尝试将 .id(UUID())
修饰符添加到您的列表中,以便丢弃动画并在更新后重新创建列表。
我有一个列表,它会在快结束时自动获取更多数据:
struct AdCardListView: View {
@ObservedObject var model: AdListViewModel = AdListViewModel()
var body: some View {
List { ForEach(self.model.adArray.enumerated().map({ [=10=] }), id: \.element.id) { index, ad in
AdCardView(ad: ad)
.onAppear {
DispatchQueue.main.async {
let count = self.model.adArray.count
if index >= count - 5 { //5 Views to the end, start loading more.
self.model.fetch(count: count)
}
}
}
}
}
}
}
模特长得像:
final class AdListViewModel: ObservableObject {
@Published var adArray = [Ad]()
...
func fetch(count: Int = 0) {
...
DispatchQueue.main.async {
self.adArray.append(contentsOf: newAds) //<-- problem here
}
...
}
我的问题:每次@Published/@ObservedObject 修改时滚动列表时我都有一点冻结。另外,我发现 List 重新计算了所有可见视图的主体 + 上面和下面的几个视图。
但我无法确定是什么导致滚动挂起并修复它(也许冻结是转移到等于(滚动速度*渲染时间)的距离?
为什么 SwiftUI 在现有视图上重新计算主体?他们没有改变!
你能帮帮我吗?
recreation body 不应该issue.I怀疑性能问题与List的更新动画有关
您是否尝试将 .id(UUID())
修饰符添加到您的列表中,以便丢弃动画并在更新后重新创建列表。