I’ve been pulling my hair out a bit over this. I’m creating a very simple app, it simply downloads an rss feed and displays it in a UITableview, which is inside a UINavigationController. Whilst it’s downloading the feed I’m presenting a Modal View.
In my modal view I’m displaying a UIImageView and a UIActivityIndicatorView that is set to spin. I’m using ASIHTTRequest to asynchronously grab the feed and then using the either the completion block to get the response string and stop the spinner or the failure block to get the NSError and display a alert View. This all works perfectly.
I’ve then created a protocol to dismiss the modal view from the tableview which is called inside the completion block. But the modal view is never dismissed! I’ve tried pushing it into the navigation controller but exactly the same problem occurs. I even have tried setting the modal view delegate to nil but still no luck.
I’ve checked it without blocks using the ASIHTTPRequest delegate methods and it’s the same, and if I don’t present the modal view the table view is displayed normally.
Any Ideas? I’ve skipped out all the tableview delegate and datasource methods as well as the dealloc and any unused functions.
@interface MainTableViewController ()
-(void)loadModalView;
@end
@implementation MainTableViewController
@synthesize tableView;
@synthesize modalView;
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
[super loadView];
tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height) style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
[self loadModalView];
}
-(void)loadModalView
{
modalView = [[ModalViewController alloc]init];
modalView.delegate = self;
[self presentModalViewController:modalView animated:NO];
}
//Modal View Delegate
-(void)downloadComplete
{
modalView.delegate = nil;
[self dismissModalViewControllerAnimated:NO];
}
@end
@interface ModalViewController ()
- (void)loadView
{
[super loadView];
backgroundImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
[self.view addSubview:backgroundImage];
spinner = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.frame = CGRectMake(160, 240, spinner.bounds.size.width, spinner.bounds.size.height);
spinner.hidesWhenStopped = YES;
[self.view addSubview:spinner];
[spinner startAnimating];
NSString* urlString = FEED_URL;
NSURL* url = [NSURL URLWithString:urlString];
ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
// Use when fetching text data
NSString *responseString = [request responseString];
[spinner stopAnimating];
[delegate downloadComplete];
// Use when fetching binary data
}];
[request setFailedBlock:^{
NSError *error = [request error];
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:@"Error" message:error.description delegate:self cancelButtonTitle:@"Continute" otherButtonTitles: nil];
[alert show];
[alert release];
}];
[request startAsynchronous];
}
Matt
The only way I solved this error was to synchronously download the data and push and pop the download view onto the navigation stack. Not ideal but it works.