UIViewRepresentable:从 updateUIView 重新加载 UICollectionView 中的数据失败,应用程序崩溃

问题描述 投票:0回答:1

我正在使用 UICollectionView 作为 UIViewRepresentable。当当前项目发生更改(滚动到当前项目并突出显示它)或源数据更新(可以添加/删除一项)时,应该更新它。第一种情况工作正常,但第二种情况可能会导致滞后,甚至导致应用程序崩溃,并出现以下异常:“当第 0 节中只有 9 个项目时,尝试将集合视图滚动到越界项目 (9) “。这是更新源数据(添加/删除项目)后滚动时引起的。

这是 updateUIView 函数的代码:

func updateUIView(_ uiView: UICollectionView, context: Context) {
        uiView.reloadData()

        if !sections.isEmpty, currentSectionId != context.coordinator.currentSectionIndex && uiView.numberOfItems(inSection: 0) == sections.count {
            context.coordinator.currentSectionIndex = currentSectionId
            
            guard let currentSection = sections.firstIndex(where: { $0.id == currentSectionId }) else { return }
            let indexPath = IndexPath(row: currentSection, section: 0)

            uiView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
        }
    }

这是我的 UIViewRepresentable 的变量:

struct SectionScrollView: UIViewRepresentable {
    @Binding var sections: [MenuSection]
    @Binding var currentSectionId: Int

这是一个可以通过类别导航的菜单,因此滚动主菜单(也是 UIViewRepresentable UICollectionView)会触发 currentSectionId 将部分集合视图滚动到当前部分。在部分集合视图中按当前部分会触发主集合视图滚动到当前部分的开头。

此外,将项目设为收藏夹会添加附加部分(如果没有收藏夹)并删除它(如果用户从收藏夹中删除最后一个项目)。而这里就是出现异常的时候。如果用户在收藏项目后滚动主集合视图,应用程序可能会崩溃(或不能)。

看来 reloadData() 并不总是有效或按预期工作。

那么,这里可能出了什么问题?

附注当我将下面的代码添加到 updateUIView 时,滚动有时会停止,直到没有添加/删除另一个最喜欢的菜肴:

uiView.reloadData() // This was already there

if sections.count != uiView.numberOfItems(inSection: 0) {
    uiView.reloadData()
}
ios swift swiftui uicollectionview uiviewrepresentable
1个回答
0
投票

reloadData应该在主线程上执行(你不应该在updateUIView中调用它) 考虑在 UIViewRepresentable 中创建协调器

© www.soinside.com 2019 - 2024. All rights reserved.