views:

184

answers:

1

I have a UITableViewController and when I push a particular view onto the stack it takes forever so I wanted to add a spinner to the cell before moving along. The problem I'm having is that the spinner gets added after the new view gets pushed onto the controller stack. But I thought that messages were synchronous?

So how can I make this spinner display before moving onto the next view? Thanks in advance!

- (void)
    tableView: (UITableView *) tableView
    didSelectRowAtIndexPath: (NSIndexPath *) indexPath {

    UITableViewCell *cell = [ self.tableView cellForRowAtIndexPath: indexPath ];

    if (cell.accessoryType == UITableViewCellAccessoryDisclosureIndicator) {
        UIActivityIndicatorView *activityIndicator = [ [ UIActivityIndicatorView alloc ] initWithFrame: CGRectMake(260.0, 10.0, 25.0, 25.0) ];
        activityIndicator.hidesWhenStopped = YES;
        activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;

        [ cell addSubview: activityIndicator ];
        [ activityIndicator startAnimating ];

        TableDemoViewController *newViewController = [ [ TableDemoViewController alloc ] initWithPath: cell.textLabel.text ];
        UINavigationController *navigationController = [ appDelegate navigationController ];
        [ navigationController pushViewController: newViewController animated: YES ];
        [ activityIndicator stopAnimating ];
    }
}
+1  A: 

If simply initing TableDemoViewController is what's so intensive, you've got other problems. Remember, the main thread is synchronous, as you pointed out. You have a couple options:

  • It's possible that simply spinning the run loop once after adding the spinner will fix your problem. You can do this by splitting your method in two, and calling the second part with the TableDemoViewController init in it from performSelector:withObject:afterDelay: with a delay of 0.
  • You probably want to find out why init is so expensive, and move that off the main thread. I highly recommend learning how to use NSOperations and NSOperationQueue. You could use the delegate pattern or an NSNotificatin to let the callers know when your expensive operation is done.

In general, if you have something that's blocking processing on the main thread like this, that's bad. You want to move that off the main thread ASAP. The main thread is where input events and animations happen -- the ability of the main thread to run freely is what keeps your app responsive and snappy. Remember, even if the user can't advance the state of your application, there's probably a lot she can interact with and a lot she can see.

Colin Barrett
Thanks for the wising, you're absolutely right that it should be moved off the main thread. Thanks a lot!
Chuck Vose