• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - Realm Swift 使用部分更新 collectionView

[复制链接]
菜鸟教程小白 发表于 2022-12-12 23:33:52 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

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

我关注了docs添加通知,以便我的结果对象中的更改将触发 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)
    }
}

我很清楚 updateUI(with: changes) 中的问题是 IndexPaths 被硬编码为第 0 节。当我编辑一个项目时,我的应用程序因此崩溃,所以我搜索周围遇到了this GitHub上的问题。 Pawelkata(评论员)提到,该问题的快速修复(现已关闭)是在 switch 语句的 update 案例中调用 collectionView.reloadData()。 p>

func updateUI(with changes: RealmCollectionChange<Results<Outfit>>) {
    switch changes {
    case .initial(_):
        collectionView.reloadData()
    case let .update(_, deletions, insertions, modifications):
        collectionView.reloadData()
        break
    case let .error(error):
        print(error.localizedDescription)
    }
}

虽然快速修复适用于修改和插入,但在删除的情况下会失败。这是因为新数据是在其他地方添加/修改的,但删除发生在同一个 viewController 上,因此这些更改实际上不会更新 UI。

我找到了 this密切相关的 stackoverflow 问题,@jpsim 回答了某人关于在 tableView 中有多个部分的问题。在@MikePollard 的评论中询问是否可以将带有多个部分的 tableView 与 Realm 集合通知结合起来。 JPSim 说这很棘手,但有可能。虽然我有一个 collectionView 而不是 tableView 我假设这也是可能的。

我尝试过的:

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

    然后我在 didSelectItem 中设置,并在 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.deleteItems(at: [self.indexPathForDeletion])
            }, completion: { (completed: Bool) in
                self.collectionView.reloadData()
            })
            break
        case let .error(error):
            print(error.localizedDescription)
        }
    }
    

    应用程序由于未捕获的异常“NSInternalInconsistencyException”而崩溃,终止应用程序,原因:“无效更新:第 2 节中的项目数无效。更新后现有节中包含的项目数 (2) 必须等于更新前该节中包含的项目数 (2),加上或减去从该节插入或删除的项目数(0 插入,1 删除),加上或减去移入或移出的项目数该部分的内容(0 移入,0 移出)。'

    我从 2 个项目开始,我删除了 1 个项目,我应该还剩下 1 个项目,但似乎我还有 2 个。这是我对错误的解释。我的解释正确吗?为什么不删除项目?

  2. 我有一个哈希表来存储这些部分,它是结果数组,所以我创建了一个函数来更新哈希表,然后重新加载 collectionView。

    func refreshData() {
        getOutfitsByCategory()
        collectionView.reloadData()
    }
    
    func getOutfitsByCategory() {
        for category in categories {
            outfitsByCategory[category] = outfits.filter("category = %@", category)
        }
    }
    

    这给了我一个“更好”的结果,但似乎有些奇怪。我可以删除它们在索引 0 处的项目 iff,无论部分如何。但是,删除索引 0 处的项目将删除它所在的整个部分。

我错过了什么?



Best Answer-推荐答案


根据您的 Collection View 有多少个部分,为每个部分的每组结果简单地设置一个单独的通知 block 可能会更容易。这需要为每个部分(以及随后的通知 token )维护一个单独的 Results 对象,因此根据您拥有的部分的数量,此解决方案可能会有些复杂。

另一个考虑可能是试用 RBQFetchedResultsController .这是在 Realm 中可用更改通知之前构建的 Controller (作为 Realm 员工的第三方项目),因此虽然它不像主集合通知系统那样“原生”,但它也可以解释表/ Collection View 部分。

关于ios - Realm Swift 使用部分更新 collectionView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41535521/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap