UICollectionView Reloading Data - ios

A question regarding reloading data in your UICollectionView.
When using reloadData it only does this once any scrolling has finished. Then there is a small pause where the collection view freezes and cannot be interacted with until the new data is loaded in. How can I get around this?
For example, I would have a view comprised of maybe 10/20/30 items, each with an image and label. I then update my dictionary with new images and strings and then reload the view to add these new items.
Many thanks.
EDIT:
On closer inspection, its not the reloading that causes the pause, its some other code, where I fetch some data. Why might this freeze my view though when i am not even reloading it to make changes to it?
I am fetching this data from -(void)scrollViewDidScroll:(UIScrollView *)scrollView
EDIT 2:
Ok here is some basic code
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self myMethodWithCompletionBlock:^(NSMutableDictionary *results, NSString *nextPageToken) {
//No code in completion block is ever called when the method is called in the dispatch block! Regardless of what it is.
}
});

Related

The best way to update multiple cells in a collection view?

I have a collection view with a flow layout that shows multiple cells. Every cell has some async loading happening before it displays an image and some text. What is the best way to update these cells in succession?
I am doing something like this that works but I'm noticing my collection view gets frozen for a second or so if multiple cells get finished at the same time.
dispatch_async(dispatch_get_main_queue(), ^{
[collectionView reloadItemsAtIndexPaths:#[indexPath]];
});
It would be nice to add some more of your code, But it is actually better to do this kinda stuff with performBatchUpdates instead of doing it in main thread.
- (void)performBatchUpdates:(void (^)(void))updates
completion:(void (^)(BOOL finished))completion;
Here is the documentation

How do display a refreshed view without touching it first?

Well, the title already says it all. I have a view (a table view in my special case embedded in a non-table view controller) and at some time in code I want to update cells and display the update. The first part works like a charm but the changes won't displayed after the reloadData() - and even when I call setNeedsDisplay() afterwards.
When the controller has to update something the tableview will be also re-drawn and the changes are visible. As soon as I touch the tableview cell the changes are also visible. Without touch the update just isn't displayed.
I've come across this issue and using GCD should solve it
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});

Why crashes UISearchBar after reload TableView

I have tableView with UISearchBarDisplayController. The below code was fetch record from webserver and display the tableview cell every works fine. but when will scroll 3 or 5 time downwards and upwards through i will going to click search bar it will crash the crash report NSLog doesn't print anything.
Remember i tried NSZombie , breaking point,exception point etc., but nothing helps.
Important question:
How to load data to tableview after fetched data from webserver. because tableview delegates methods are called before fetching data from server.
DataFetchController *getDataFetch=[[DataFetchController alloc]init];
//getleadFetch.delegate=self;
[getDataFetch beginTaskWithCallbackBlock:^(NSArray *mm){
[self.tableView reloadData];//if i comment this line the UISearchBar not crashes
}];
Loading the tableview before the data fetch is complete will obviously result in a crash.
So to avoid that we need to know when the data fetch is complete.
This can be easily obtained from your sql apis which return an error code when the fetch is complete. You can via that to find out if the fetching is complete or not.So sequentially you can provide the reloading of your table view command.
Hope it helps!!
update tableview data in main thread it not crash.
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});

UITableView weird reloadData issue

I am stuck in a really weird issue, What em doing is calling NSURLConnection sendAsynchronousRequest in which i reload tableView and it does it without any issue. This scenario works fine while em standing on the same ViewController while request response is received. The issue arises when I call sendAsynchronousRequest and move from that ViewController and then come back to it before the request gives the response. This time the TableView reloadData gets called but doesn't do anything on the View. I call the reloadData in this dispatch_async(dispatch_get_main_queue(), ^{}); for it to run on mainThread.
Any help in this regard would be great.
Edit 1:
Here's what i have gotten far till now.. when i start the NSURLConnection asyncRequest it keeps the reference to the tableView and array that it has at that current time.. But when i navigate off from that view and then come back the view is reinitialized so the tableView and array has new references. So when the asyncRequest calls tableView ReloadData, it calls reload for the older referenced tableView rather than the one that is now visible hence not reloading the tableView… hope now you can help.
Rather than reloading tableview on main thread, try to reload it once you get data and the data is parsed. Switching between views may cause your tableview to reload before the data comes from server resulting blank tableview and this is caused due to calling some methods on main thread.
EDIT: Try to initialize tableview in viewdidload only and array just after you get response from server and before loading data in it.

View displaying on top of loading icon due to async call

I was doing everything in a single thread and have just started moving to asynchronous calls so I'm a bit confused.
What I would like is for the view to load, either with an empty table or with no table at all. The MBProgressHUD should show while the async call gets the data. Then when the data is found the HUD goes away and the table refreshes.
What I have now is everything works except that the HUD is displayed underneath the empty table. Here is the most relevant code.
- (void)awakeFromNib
{
[super awakeFromNib];
[MBProgressHUD showHUDAddedTo:self.tableView animated:YES];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
self.dataController = [[StudyController alloc] initWithCredentials:email password:password];
dispatch_sync(dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.tableView animated:YES];
[self.tableView reloadData];
});
});
}
Basically what is happening, I think, is all my code that was rendering the table correctly runs once while the async call is running, and shows an empty table on top of the HUD, and then again after the call when I tell it to reloadData. How do I get it to not run that first time?
Thanks.
It's hard to gauge without seeing your table view delegate/datasource methods, but your intuition makes sense. In this case, I can see two options:
Add some logic to your delegate/datasource methods to properly show your loading view if the table is empty.
Rather than add the loading view to the table view, add the loading view to the table view's superview. That way, you can ensure that the loading view is always on top of the table view.
I usually opt for the second method, because I prefer to focus my datasource and delegate methods on only the table view.
Hope this helps!

Resources