【问题标题】:Updating Data and Reloading the CollectionView更新数据并重新加载 CollectionView
【发布时间】:2017-06-11 21:21:22
【问题描述】:

我正在尝试更新包含我的 collectionView 数据的数据对象(只是过滤数据模型),并希望使用过滤后的数据重新加载 collectionView。问题是在重新加载我得到的 collectionView 和重新加载发生时错误 indexPath out of range 时。似乎在调试时,collectionView 正在尝试重新加载原始数据对象,而不是过滤的数据对象。我做错了什么:

func handleFilterAction(sender: FilterButton){
    guard let type = sender.buttonFilterType else {return}
    switch type {
    case .FilterAll:
        return
    case .FilterDay:
        return
    case .FillterWeek:
        return
    case .FilterMonth:
        collectionView?.performBatchUpdates({ 
            let objects = FilterDataManager.filterDataWith(currentLocalData: &self.eventObjects, filterOption: .ThisMonth)
            self.eventObjects.removeAll()
            self.eventObjects = objects
        }, completion: { (completion) in
            self.navigationItem.title = "This Month"
            self.collectionView?.reloadData()
        })
    }

    self.handleShowFilterView()

}

eventObjects 是 collectionView 应该为数据读取的内容:

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return eventObjects[section].sectionObjects.count
}

【问题讨论】:

    标签: ios swift uicollectionview


    【解决方案1】:

    当您想要对collectionView 的更改进行动画处理时,您可以调用performBatchUpdates。 iOS 期望您调用诸如 collectionView?.insertItems(at: [IndexPath])collectionView?.deleteItems(at: [IndexPath]) 让它知道您正在插入和删除什么,以便它可以为它设置动画。对于这两个调用,您传入一个包含所有被插入或删除的IndexPaths 的数组。

    执行此操作时,iOS 会期望 collectionView 中现在的项目数。公式为:

    newItemCount = previousItemCount - deletedItemCount + insertedItemCount
    

    在您的情况下,您修改了您的 模型,但您从未调用过 insertItemsdeleteItems 方法,因此 iOS 仍然认为所有项目都在那里。正是您的 modelcollectionView 之间的这种脱节导致了您的问题。

    要解决此问题,您需要执行以下操作之一:

    1. 调用deleteItemsinsertItems,使用您要删除和插入的IndexPaths 数组(先调用delete)。
    2. 或者,忘记performBatchUpdates,只需更新您的模型数据并致电reloadData

    另外,请确保 numberOfSections 正在返回 eventObjects.count

    【讨论】:

    • 感谢您的回复,所以我删除了 performBatchUpdates() 调用,现在只是在模型上执行更新后调用 reloadData(),但仍然得到相同的错误,调试时我我注意到模型已用数据更新,并且第一部分被正确看到,但似乎仍在期待第二部分。
    • 并且更新后的对象模型自过滤后只有一个。
    • 您是否希望过滤只保留一个部分的数据?
    • 我不熟悉FilterDataManager。也许您需要为每个部分单独调用它。类似for sectionNum in eventObjects.indices { var data = eventObjects[sectionNum]; let objects = FilterDataManager.filterDataWith(currentLocalData: &data, filterOption: .ThisMonth); eventsObjects[sectionNum] = objects }
    • 另外,确保numberOfSections 函数返回eventsObjects.count
    猜你喜欢
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    相关资源
    最近更新 更多