Issue
You are downloading data and loading it to the tableView async, that means your data process is executing on background, but the tableView is still active and it's shown.
My Solution
I handle this situation in two ways
You first load all the data in a NSArray
or NSDictionary
(whatever object you need) before presenting your TableViewController
, and pass it as an argument to the TableViewController
. In other words, you need to load data before presenting the tableViewController
.
You need to create an animation view, or a loading view while you are performing the download of the data you tell the user that data is loading so wait until the process is done. And when the process is done, simply reload the tableView and pass the data to the TableViewCells
.
Example
1) This code is used when you send request to server to get data (for example from JSON)
LoadingView *spinn = [LoadingView loadSpinnerIntoView:self.view];
dispatch_queue_t downloadQueue = dispatch_queue_create("LoadingView", NULL);
dispatch_async(downloadQueue, ^{
// do our long running process here
[NSThread sleepForTimeInterval:0.1];
// do any UI stuff on the main UI thread
dispatch_async(dispatch_get_main_queue(), ^{
//Start downloading your data, and pass data you fetched to objects of NSDictionary
//Your methods
//After downloading data is done, reload data on tableView
[tableView reloadData];
//Remove loading view, and your tableViewController is all set
[spinn removeSpinner];
});});
2) After fetching data to NSDictionary
or NSArray
from the request you made, you have also links to download images.
For downloading image async without blocking mainThread you can refer to @sonxurxo question, or you can use this one which also uses SDWebImage
You just need to #import <SDWebImage/UIImageView+WebCache.h>
to your project, and you can define also the placeholder when image is being downloaded with just this code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
cell.textLabel.text = @"My Text";
return cell;
}