I have a UINavigationController that pushes a custom UITableViewController onto the stack. This pushed view controller, which is also the the table view delegate and data source, will then need to download the required data from the internet before it can be displayed. This process of downloading also happens when the user scrolls to the bottom of the the table view, in which the new downloaded data is appended to the bottom of the table view.
I want to notify the user that this downloading is occurring. The problem is that I have tried many methods, yet the table view does not display any of the changes I have made before the downloading occurs. I have encapsulated the notification and download into a single method within my custom UITableViewController class:
- (void) extractArticlesFromURL:(NSURL) url
{
// 1st method - set alpha
self.tableView.alpha = 0.2;
// 2nd method - push an overlay while downloading
UIViewController* overlay = [[UIViewController alloc] init];
overlay.view.backgroundColor = [UIColor blackColor];
[self.navigationController pushViewController:overlay animated:NO];
// 3rd method - introduce a BOOL isLoading, which is used in data source
// and delegate methods in an attempt to change display
isLoading = YES;
[self.tableView reloadData];
[self.tableView setNeedsDisplay];
// Spend a few seconds downloading data which is stored in an
// array which is accessed during UITableViewDelegate method calls...
self.tableView.alpha = 1;
isLoading = NO;
[self.navigationController popViewControllerAnimated:NO];
[self.tableView reloadData];
}
I call this particular method in -(void)scrollViewDidScroll: (UIScrollView*)scrollView, which is definitely getting called as the table view is appended with new data but with no change in display during the downloading. I do not mind the app freezing up, it’s just it does not update the display before it freezes.
If it helps, I am using XCode 4.3.2 using LLVM 3.1, and testing the functionality with iPhone Simulator 5.1. This component of the application is single-threaded.
You get your view frozen because you are taking lots of time to complete these actions and you are running in the main thread.
The best way to unfreeze the view is to collect all the remote data using a separate thread. When you end loading data, you call your main controller and tell it to update the views (update tables, push new controller, etc).
Also, when you start loading data in the separate thread, you can update your view in the main thread i.e. adding a spinning wheel or some “Loading …” message on screen.