How do I prevent cellForItemAtIndexPath from executing before I have my data ready?

核能气质少年 提交于 2020-02-08 06:57:38

问题


I'm returning images as Base64 data from my server to my application but I'm not going to ask my server for the images until I have the users' location, which I'm only going to have after the user logs in to the application (which displays the UICollectionView).

My problem is that collectionView:cellForItemAtIndexPath: is being called before I have the data ready for the cells. Which ways could I prevent this method from being called until my NSURLConnection has received a full response from my server and I have the Base64 encoded image data?

(It may also be relevant that I'm using the UICollectionView as an NSURLConnectionDataDelegate and NSURLConnectionDelegate and I have a seperate class (RenderMetadata()) which will fetch the images.)

Edit: Thanks for all of your innovative answers! I've figured out a way to implement what I was after. I'd explain but I haven't shared my code so I don't think it's a good idea to even bring it up because that would just lead to confusion. Basically I'd added an Object to my view controller in my storyboard which referred to that class which I was using to fetch the Base64 encoded image strings from my server.


回答1:


Set collection view delegates and reload the collection when you receive the response. Before that, keep them nilled. If delegate and dataSource of the collection view are nil it won't load data.

func handleDataLoaded() 
{
    // Your code that handles data.
    ...

    // Load the collection with data
    self.collectionView.delegate = self
    self.collectionView.dataSource = self

    self.collectionView.reloadData()
}



回答2:


You need to ensure that the value returned by numberOfItemsInSection: accurately reflects the number of cells you want in your collectionview at all times - ie. If you haven't loaded any data it should return 0




回答3:


You can add a isDataLoaded flag to the view controller class, initially set to false, and changed to true once all data has been loaded.

Then, in the numberOfSections method return 0 if that flag is not set:

func numberOfSections() {
    return self.isDataLoaded ? 1 : 0
}

When all data is loaded, call the reloadData method to force a reload:

self.isDataLoaded = true
self.reloadData()

Be sure to execute that code in the main thread




回答4:


You can set the number of tows to 0 as suggested by Paulw11, OR Set the dataSource of your collectionView or tableView only when you actually want it to display the cells OR call reloadData when you are ready

But you should made it in another way, your viewController should take care of updating the collectionView with the downloaded images, and you should reaload/update/add every single cell (show it without the image or with a placeholder if appropriate) once its own image is downloaded so the user will not have to wait every image to download before see something.



来源:https://stackoverflow.com/questions/28055177/how-do-i-prevent-cellforitematindexpath-from-executing-before-i-have-my-data-rea

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!