Ios 使用节更新collectionView

Ios 使用节更新collectionView,ios,uicollectionview,realm,Ios,Uicollectionview,Realm,我有一个collectionView,我刚刚添加了部分,我正在使用RealmSwift。在添加这些部分之前,我能够对数据进行更改,并在我的collectionView中看到它们的更新/删除 func notificationSubscription(for outfits: Results<Outfit>) -> NotificationToken { return outfits.addNotificationBlock({ [weak self] (changes:

我有一个collectionView,我刚刚添加了部分,我正在使用RealmSwift。在添加这些部分之前,我能够对数据进行更改,并在我的collectionView中看到它们的更新/删除

func notificationSubscription(for outfits: Results<Outfit>) -> NotificationToken {
    return outfits.addNotificationBlock({ [weak self] (changes: RealmCollectionChange<Results<Outfit>>) in
        self?.updateUI(with: changes)
    })
}

func updateUI(with changes: RealmCollectionChange<Results<Outfit>>) {
    switch changes {
    case .initial(_):
        collectionView.reloadData()
    case let .update(_, deletions, insertions, modifications):
        collectionView.performBatchUpdates({
            self.collectionView.reloadItems(at: modifications.map { IndexPath(row: $0, section: 0) })
            self.collectionView.insertItems(at: insertions.map { IndexPath(row: $0, section: 0) })
            self.collectionView.deleteItems(at: deletions.map { IndexPath(row: $0, section: 0) })
        }, completion: { (completed: Bool) in
            self.collectionView.reloadData()
        })
        break
    case let .error(error):
        print(error.localizedDescription)
    }
}
func refreshData() {
    getOutfitsByCategory()
    collectionView.reloadData()
}

func getOutfitsByCategory() {
    for category in categories {
        outfitsByCategory[category] = outfits.filter("category = %@", category)
    }
}
我按照添加通知,这样我的结果对象中的更改将触发UI更改;请注意,我对collectionView进行了适当的更改

func notificationSubscription(for outfits: Results<Outfit>) -> NotificationToken {
    return outfits.addNotificationBlock({ [weak self] (changes: RealmCollectionChange<Results<Outfit>>) in
        self?.updateUI(with: changes)
    })
}

func updateUI(with changes: RealmCollectionChange<Results<Outfit>>) {
    switch changes {
    case .initial(_):
        collectionView.reloadData()
    case let .update(_, deletions, insertions, modifications):
        collectionView.performBatchUpdates({
            self.collectionView.reloadItems(at: modifications.map { IndexPath(row: $0, section: 0) })
            self.collectionView.insertItems(at: insertions.map { IndexPath(row: $0, section: 0) })
            self.collectionView.deleteItems(at: deletions.map { IndexPath(row: $0, section: 0) })
        }, completion: { (completed: Bool) in
            self.collectionView.reloadData()
        })
        break
    case let .error(error):
        print(error.localizedDescription)
    }
}
func refreshData() {
    getOutfitsByCategory()
    collectionView.reloadData()
}

func getOutfitsByCategory() {
    for category in categories {
        outfitsByCategory[category] = outfits.filter("category = %@", category)
    }
}
虽然快速修复可以用于修改和插入,但在删除时会失败。这是因为在其他地方添加/修改了新数据,但删除发生在同一个viewController上,因此更改实际上不会更新UI

我发现了密切相关的stackoverflow问题,@jpsim回答了某人关于在tableView中有多个部分的问题。在注释中,@MikePollard询问是否可以将具有多个节的tableView与域集合通知相结合。JPSim说这很棘手,但也有可能。虽然我有一个collectionView而不是tableView,但我假设这也是可能的

我所尝试的:

  • 因为我需要知道该项来自哪个部分,所以我创建了一个变量来存储所选项的indexPath。
    var indexpathfordelement=IndexPath()

    然后在
    didSelectItem
    中设置,并在
    updateUI(with:changes)
    中使用

    这给了我一个“更好”的结果,但似乎有些奇怪。我可以删除索引为0的项目,而不考虑节。但是,删除索引0处的项将删除它所在的整个节


  • 我遗漏了什么?

    根据集合视图的节数,可能更容易为每个节的每组结果设置单独的通知块。这需要为每个部分(以及随后的通知令牌)维护一个单独的
    Results
    对象,因此根据您拥有的部分数量,此解决方案可能会有点复杂


    另一个考虑可能是尝试一下。这是在Realm中的更改通知可用之前构建的控制器(由Realm员工作为第三方项目),因此虽然它不像主集合通知系统那样“原生”,但它也可以用于表/集合视图部分。

    谢谢@TiM!我只有十几个部分。我现在意识到我误解了你的建议,但它引导我实现了解决方案,即为每个部分设置单独的通知。然后我更新了我的哈希表并重新加载了collectionView。@MaryMartinez如何做
    单独通知