Search code examples
iosobjective-cuiviewcontrolleruitabbarcontrollerdispatch-async

UITabBarController setSelectedIndex slow performance


When a user presses the center UITabBarItem I present a modal UIView. Think of it like Instagram.

-(BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController{

if(viewController == [self.viewControllers objectAtIndex:2])
{
    CameraViewController *cameraVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"cameraVC"];
    UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:cameraVC];
    navController.navigationBar.barStyle = UIStatusBarStyleLightContent;
    [self presentViewController:navController animated:YES completion:nil];
    return NO;
}
else
{
    return YES;
}
}

This works perfectly.

When I'm done taking a picture in CameraViewController I want the view to be dismissed and the 4th UITabBarItem to be selected for the results of the picture (HistoryViewController).

This is how I do that in CameraViewController (who is modally pushed):

[self dismissViewControllerAnimated:YES completion:nil];

[(UITabBarController *)self.presentingViewController setSelectedIndex:3];

And this is where it gets buggy.

enter image description here

As you can see the text in the 4th tab is selected, but the first tab icon is still selected. Also the presented view is the one from the first tab.

After 10 seconds or so it eventually changes the view to the, correct, 4th tab.

I'm trying to find out what process creates this slowdown so I've set up a lot of NSLog's.

The approximate 10 second slowdown is between [(UITabBarController *)self.presentingViewController setSelectedIndex:3]; in the CameraViewController and viewDidLoad in HistoryViewController.

What is happening in between these calls/methods that could cause the slowdown?

Edit:

In CameraViewController:

- (void)scan {
dispatch_queue_t scanTesseract = dispatch_queue_create("scanTesseract", NULL);

dispatch_async(scanTesseract, ^(void) {
    dispatch_async(dispatch_get_main_queue(), ^{
        [SVProgressHUD setForegroundColor:[UIColor ht_mintDarkColor]];
        [SVProgressHUD showProgress:0 status:@"Scanning"];
    });

    //background processing goes here
    [self.tesseract setImage:self.imgToScan.blackAndWhite];
    [self.tesseract recognize];
    [self filterResults:[self.tesseract recognizedText]];
    dispatch_async(dispatch_get_main_queue(), ^{
        [SVProgressHUD dismiss];
    });
    [self scanningDone];
});
}

- (void)scanningDone {
[LastScan getInstance].hasBeenViewed = FALSE;

[self dismissViewControllerAnimated:YES completion:nil];

[(UITabBarController *)self.presentingViewController setSelectedIndex:3];
}

In HistoryViewController:

- (void)viewDidLoad {
[super viewDidLoad];

NSLog(@"ViewDidLoad");
self.navigationController.navigationBar.barStyle = UIStatusBarStyleLightContent;

self.collectionView.backgroundColor = [UIColor whiteColor];
}

Solution

  • You are calling your scanningDone from within a background queue. Execute that method on the main Queue.

    dispatch_async(dispatch_get_main_queue(), ^{
       [self scanningDone];
    });