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?
This may help you (without additional information, I can't really say).
UITabBarController
conforming to <UITabBarControllerDelegate>
UITabBarController
, be sure to set self.delegate = self;
in viewDidLoad
shouldSelectViewController
YES
(i.e. allow the tab to be selected)NO
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."