SwiftUI 列表在 @ObservedObject 更新时冻结

4

我有一个列表,当接近末尾时会自动获取更多的数据:

struct AdCardListView: View {
    @ObservedObject var model: AdListViewModel = AdListViewModel()

    var body: some View {
        List { ForEach(self.model.adArray.enumerated().map({ $0 }), 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会重新计算现有视图的主体?它们没有改变!

你能帮助我吗?

1个回答

3

重建身体不应该是问题。我怀疑性能问题是否与列表更新动画相关。

您是否尝试将.id(UUID())修饰符添加到列表中,以便在更新后丢弃动画并重新创建列表。


是的,我尝试过了,但没有任何改变。但我只在行内的顶级视图上尝试过。我需要在顶级视图内的所有视图上设置ID吗? - Fedyanint Timofey
1
这个答案对我有帮助:https://www.hackingwithswift.com/articles/210/how-to-fix-slow-list-updates-in-swiftui - grantespo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接