I have a UITableView which from an external RSS feed.
When you select a row it uses navigationController and slides in from the right, the problem is that the RSS feed contains images therefore it can can take a few seconds to load and without any indication of what is going on you can mistake it for an application crash.
I decided to add a spinner so that you know that new page is loading.
Here is my code:
RootViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"Loading New Page");
[tableView deselectRowAtIndexPath:indexPath animated:YES];
DetailsViewController *detailViewController = [[DetailsViewController alloc] initWithNibName:@"DetailsViewController" bundle:nil];
detailViewController.item = [rssItems objectAtIndex:floor(indexPath.row/2)];
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.center = CGPointMake(160, 240);
[self.view addSubview:spinner];
[spinner startAnimating];
[spinner release];
}
DetailsViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSString *imgURL = [item objectForKey:@"image"];
NSData *mydata = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imgURL]];
item_photo.image = [[UIImage alloc] initWithData:mydata];
item_title.text = [item objectForKey:@"title"];
item_date.text = [NSString stringWithFormat:@"Date: %@",[item objectForKey:@"date"]];
item_time.text = [NSString stringWithFormat:@"Time: %@",[item objectForKey:@"time"]];
item_cost.text = [NSString stringWithFormat:@"Cost: £%@",[item objectForKey:@"cost"]];
item_info.text = [item objectForKey:@"description"];
self.navigationItem.title = @"Event Type";
}
There are two problems with this code.
If anyone could help me with this problem i would be truly gratefully.
Step 1: Add a background with a spinner gif on top of the page, then remove them when everything is loaded. Step 2: Add a little script right after the opening body tag to start displaying the load/splash screen.
You are adding the activity indicator view to the view of the controller which is pushing the detail view controller, so you wont see it anyway
try moving the second group of code to the viewDidLoad method of DetailsViewController, you can call stopAnimating on the activity indicator when you are finished loading. To get a reference to the UIActivityIndicator you should add a tag
e.g. in viewDidLoad
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.center = CGPointMake(160, 240);
spinner.tag = 12;
[self.view addSubview:spinner];
[spinner startAnimating];
[spinner release];
in the loadingFinished method (whichever method is called when finished loading)
[[self.view viewWithTag:12] stopAnimating];
You need to do some work in a background thread. If the following line is the one that takes the time:
detailViewController.item = [rssItems objectAtIndex:floor(indexPath.row/2)];
Then you could do this in the background with GCD:
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// This is the operation that blocks the main thread, so we execute it in a background thread
id item = [rssItems objectAtIndex:floor(indexPath.row/2)];
// UIKit calls need to be made on the main thread, so re-dispatch there
dispatch_async(dispatch_get_main_queue(), ^{
detailViewController.item = item;
[spinner stopAnimating];
});
});
And +1 to @wattson12 - you need to add the spinner to the new view instead. Alternatively you could add the spinner to the current view, and instead put the pushViewController
call into your GCD main-queue block.
Final point - you'll want to remove the spinner from its superview once you stop it animating. Alternatively, you can have a single instance of the spinner, and set hidesWhenStopped
to YES.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With