views:

110

answers:

1

I've been trying for about a day to get a table cell to display an activity indicator while it loads a new view. Upon didSelectRowAtIndexPath I'd like to display the indicator while the following runs

[self.navigationController pushViewController:subKeywordController animated:YES];

This controller then runs a fairly intensive SQL query

I've searched the web and read dozens of posts but none seem to help with my specific problem. I understand that I need to run the indicator in another thread because the push and subsequent load takes precedence but I'm unsure how to do it. I thought about running the SQL query in the controller before but that's getting very messy.

The odd thing is that I've been using MBProgressHUD to display busy cursors in this same table view with no issues. It's only when I apply a search and then select one of the results that causes this error:

bool _WebTryThreadLock(bool), 0x1d79b0: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...

The app continues on the iPhone but crashes the simulator.

Any help would be greatly appreciated.

+1  A: 

The problem is that your task in the controller is holding up the UI code (but you probably already know that!). A cheap and easy way of solving this is to put a tiny delay on starting your slow task (in this case your SQL query) using a timer :

- (void)viewDidLoad {
    [super viewDidLoad];

    // instead of running the SQL here, run it in a little bit
    [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(doSQL:) userInfo:nil repeats:NO];

    // Show the please wait stuff
    [activityIndicator setHidden:NO];
}

- (void)doSQL:(NSTimer *)timer {
    // Do your sql here
}

The other way of solving this is to move your SQL into a seperate thread :

- (void)viewDidLoad {
    [super viewDidLoad];

    // instead of running the SQL here, run it in a little bit
    [self performSelectorInBackground:@selector(doSQL) withObject:nil];

    // Show the please wait stuff
    [activityIndicator setHidden:NO];
}

- (void)doSQL {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // Do your sql here

    // Tell the main thread
    [self performSelectorOnMainThread:@selector(doneSQL) userInfo:nil waitUntilDone:YES];

    // Cleanup
    [pool release];
}

- (void)doneSQL {
    // Update your UI here
}

Hope that helps!

deanWombourne
Thanks. I was coming on here to delete this as it was a silly mistake on my part in not calling 'resignFirstResponder'But thanks for the answer though.
Matt