.reloadData()而没有重新创建可见单元格或内存中的那些?

时间:2018-02-07 12:31:34

标签: ios swift uitableview uicollectionview uicollectionviewcell

当我实例化第三个单元格时,我会将更多内容添加到我的模型数组中,然后我将使用以下内容更新集合视图数据:

DispatchQueue.main.async(execute:  {
    self.collectionView.reloadData()
})

一切都按预期工作。但是,当我为我的collectionView重新加载数据时,它将实例化当前可见或保留在内存中的单元格(2,3)。不幸的是,我有一些昂贵的服务器请求,耗费了大量的时间。

Instaniated  0
Instaniated  2
Instaniated  3

******polluting more data: size of cells 10

Instaniated  2
Instaniated  3
Instaniated  4

如何在不重新创建可见单元格或内存中的数据的情况下重新加载数据?

非常感谢。

3 个答案:

答案 0 :(得分:1)

尝试插入或重新加载实际更改过的单元,而不是重新加载单元格。您可以使用UIColletionView s performBatchUpdates(_:)Link

一个例子:

collectionView.performBatchUpdates {
  self.collectionView.insertItems(at: [IndexPath(row: 1, section: 1)])
}

这确保仅加载新单元格。您还可以在此方法中移动单元格和节,甚至删除单元格。链接页面包含所有这些的文档。

答案 1 :(得分:0)

为什么你不能采用以下方法

1)我希望你已经将dataSource和collectionView对象声明为类的全局

let collectionView = UICollectionView()
var dataSource = [Any]()

2)有一个函数可以从API响应中获取初始结果

func getInitialPosts(){
    // call api
    // store your initial response in the local array object and reload collectionview
    let results:[Any] = {response from the server call}
    self.dataSource.append(contentsOf: results)
    DispatchQueue.main.async(execute: {
        self.collectionView.reloadData()
    })
}

3)对于下一个电话,你可以有另一个功能

func getPostsForPage(page:Int){
    // call api with page number
    let newResults = {response from the server call}
    self.dataSource.append(contentsOf: newResults)

    var indexPathsToReload = [IndexPath]()
    let section = 0
    var row = self.dataSource.count - 1

    //add new data from server response
    for _ in newResults {
        let indexPath = IndexPath(row: row, section: section)
        row+=1
        indexPathsToReload.append(indexPath)
    }

    // perform reload action
    DispatchQueue.main.async(execute: {
        self.collectionView.insertItems(at: indexPathsToReload)
    })
}

答案 2 :(得分:0)

假设您正在从您的网络适配器调用具有新数据的委托函数 fetchData。在这里您必须检查您的数据是否为空,以检查您是否需要添加新数据或重新加载整个 CollectionView。

然后创建所有需要获取更多的 indexPath,以便让已经获取的单元保持原样。最后使用 insertItems(at: IndexPaths)。

我使用 page 是为了将来用页码对新数据进行分页。严格适用于我的用例。祝你好运!

func fetchData(with videos: [VideoModel], page: Int) {
    guard self.data.count == 0 else{
        self.addNewData(with: videos, page: page)
        return
    }
    self.data = videos
    DispatchQueue.main.async {
        self.isPaging = false
        self.collectionView?.reloadData()
        self.page = page
    }
}
func addNewData(with videos: [VideoModel], page: Int){
    var indexPathsToReload = [IndexPath]()
    let section = 0
    var row = self.data.count - 1
    self.data += videos
    for _ in videos {
        print(row)
        let indexPath = IndexPath(row: row, section: section)
        row+=1
        indexPathsToReload.append(indexPath)
    }
    DispatchQueue.main.async{
        self.isPaging = false
        self.collectionView!.insertItems(at: indexPathsToReload)
        self.page = page
    }
}