iosobjective-cuitabbarcontrolleruitabbaruitabbaritem

Is there any delegate that serves the purpose of tabBar willSelectItem?


I need to do some UI tasks when user selects a UI tab item. Following delegate is available,

-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item

Although, to answer for my particular question the internal UI transition issue is not important here, I am still sharing a overview code snippet.

-(void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
{
    AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
    [delegate.rootTabBarController showConsentErrorPage];
}

However, my UI task inside this delegate shows a glitch on the transition as it does the work after the tab is already shown. I want to perform the UI task first before the UI being visible. Any such delegate of trick to resolve this issue?


Solution

  • This may help you (without additional information, I can't really say).

    Here is some sample code...

    With this option, we present the "Ask Consent" controller, and only navigate to the "needs consent to see" tab when the user selects "Yes":

    - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
        
        if ([viewController isKindOfClass:NeedsConsentViewController.class]) {
            
            NeedsConsentViewController *vc = (NeedsConsentViewController *)viewController;
            
            // whatever you're using to track the user's consent
            if (vc.hasConsent) {
                // allow the tab to be selected
                return YES;
            }
            
            // configure / instantiate your "Consent" view controller
            UIAlertController * alert = [UIAlertController
                                         alertControllerWithTitle:@"Yes/No"
                                         message:@"Need your consent..."
                                         preferredStyle:UIAlertControllerStyleAlert];
            
            UIAlertAction* okButton = [UIAlertAction
                                       actionWithTitle:@"Yes"
                                       style:UIAlertActionStyleDefault
                                       handler:^(UIAlertAction * action) {
                
                // however you're setting your user consent tracking
                vc.hasConsent = YES;
                
                // show that tab
                [self setSelectedViewController:vc];
                
            }];
            
            [alert addAction:okButton];
            
            UIAlertAction* noButton = [UIAlertAction
                                       actionWithTitle:@"No"
                                       style:UIAlertActionStyleDefault
                                       handler:^(UIAlertAction * action) {
                
                // user said NO... nothing else to do
    
            }];
            
            [alert addAction:noButton];
            
            [self presentViewController:alert animated:YES completion:nil];
            
            // don't show the tab
            return NO;
        }
        
        // all other tabs
        return YES;
    }
    

    With this option, we present the "Ask Consent" controller and navigate to the "needs consent to see" tab behind it. If the user answers "No" we navigate back to the previously selected tab:

    - (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
        
        NSInteger curTabIDX = self.selectedIndex;
        
        if ([viewController isKindOfClass:NeedsConsentViewController.class]) {
    
            NeedsConsentViewController *vc = (NeedsConsentViewController *)viewController;
    
            // whatever you're using to track the user's consent
            if (vc.hasConsent) {
                // allow the tab to be selected
                return YES;
            }
    
            // configure / instantiate your "Consent" view controller
            UIAlertController * alert = [UIAlertController
                                         alertControllerWithTitle:@"Yes/No"
                                         message:@"Need your consent..."
                                         preferredStyle:UIAlertControllerStyleAlert];
            
            UIAlertAction* okButton = [UIAlertAction
                                       actionWithTitle:@"Yes"
                                       style:UIAlertActionStyleDefault
                                       handler:^(UIAlertAction * action) {
                
                // however you're setting your user consent tracking
                vc.hasConsent = YES;
                
                // we've already navigated to the tab, with the Consent VC presented on top of it
                //  so nothing else to do
                
            }];
            
            [alert addAction:okButton];
            
            UIAlertAction* noButton = [UIAlertAction
                                       actionWithTitle:@"No"
                                       style:UIAlertActionStyleDefault
                                       handler:^(UIAlertAction * action) {
                
                // user said NO, so return to the previous tab
                [self setSelectedIndex:curTabIDX];
                
            }];
            
            [alert addAction:noButton];
            
            [self presentViewController:alert animated:YES completion:nil];
    
            // show the tab behind the Consent VC
            return YES;
        }
        
        // all other tabs
        return YES;
    }
    

    Note: This is Example Code Only and is not intended to be, nor should be considered, "production ready."