Question

I have three View Controllers (A, B, C) that are displayed when user clicks on Tab Bar item. When the user clicks on the third Tab Bar item, the C View Controller is displayed. The problem is that when third Tab Bar is selected it triggers a function that does a bunch of calculations and creates UI elements and I would like to display an Activity Indicator while those tasks are being done.

Right now I have a situation where that time consuming function blocks the main thread, so when user clicks the third Tab Bar item the UI freezes and the C View Controller is displayed when the time consuming function has done its job. But I would like to display the background of C View Controller with a spinner, while the function executes. So I tried to move the time consuming function to a new thread, but I can't get it to work.

In my CViewController.m in - (void)viewDidLoad I have:

activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityView.frame = CGRectMake(0, 0, 35, 35);
activityView.center = self.view.center;
[self.view addSubview:activityView];
[activityView startAnimating];

[NSThread detachNewThreadSelector:@selector(thirdTabClicked) toTarget:self withObject:nil];

Then comes the function - (void)thirdTabClicked:

//Bunch of code here...

[activityView performSelectorOnMainThread:@selector(calculationDone) withObject:nil waitUntilDone:NO];

And the -(void) calculationDone looks like this:

-(void) calculationDone {
    [activityView stopAnimating];
    [activityView removeFromSuperview];
}

But it does't work. Maybe it has got something to do with the fact that I have a custom class for UITabBarControllerDelegate, so the thirdTabClicked is actually called from there. So my TabBarControllerDelegate.m looks like this:

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {

if ([viewController respondsToSelector:@selector(secondTabBarClicked)]) {        
    [(id)viewController secondTabBarClicked];
}

if ([viewController respondsToSelector:@selector(thirdTabClicked)]) {
    [(id)viewController thirdTabClicked];
}
}
Was it helpful?

Solution

You can try this

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    //Fire api
dispatch_async(dispatch_get_main_queue(), ^{
    //   update UI
});
});

OTHER TIPS

I wonder why you are customizing UITabBarControllerDelegate and directly call the method thirdTabClicked? The method is called in viewDidLoad already so I think is is not necessary to call it from TabbarController delegate.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top