Disable action - user taps on tabbar item to go to root view controller - iphone

I want to disable the default action when user taps the tabbar item.
For example, i have a tabbar with Tab1, Tab2 and Tab3. In Tab1, user can navigate from View1 to View3 (View1 > View2 > View3). If user is at View3, and he taps the Tab1, the application takes the user to View1 (the root view controller). I want to disable this functionality. I don't want the tap on Tab1 to pop all the view controllers. How can i do that?
Edit:
This behavior is a little strange, but a handy shortcut in case of deep hierarchy!
You can implement following UITabBarControllerDelegate methods to disable this system wide shortcut:
#pragma mark -
#pragma mark UITabBarControllerDelegate
- (BOOL)tabBarController:(UITabBarController *)tbc shouldSelectViewController:(UIViewController *)vc {
UIViewController *tbSelectedController = tbc.selectedViewController;
if ([tbSelectedController isEqual:vc]) {
return NO;
}
return YES;
}

if you look at the UITabBarController delegate there is a method:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
If you implement this in your class, you can check if the UIViewController is the already displayed one and then return NO, which will stop this from happening.
I had the same problem with a ABPeoplePicker object embedded in a UITabBarController, in that pressing the 'Contacts' tab a second time which was already displayed would make the ABPeoplePicker control show the 'Groups'

Related

iOS - is it possible to select view for a uitabbar at runtime?

I am assigning my view controller to my tab right after I create it. Is it possible to select the view that will show after the tab is clicked?
For eg
//user clicks tab 1
if(hasMessages)
//show view A
else
//show view B
Yes, it is possible. You need to set a delegate for your tab controller:
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
tabBarController.delegate = self; // or whatever suitable class you have
This delegate needs to conform to the UITabBarControllerDelegate protocol.
In your delegate, implement tabBarController:didSelectViewController: and inside it, find out which view you want to present. Assuming your tab's root view controller is a navigation controller, then the delegate method implementation would be something like this:
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController {
/* logic goes here */
[viewController pushViewController:someNewVC animated:YES];
}

TabBatController with viewControllers

In my tabBarController-based app, I have four tabs - tabA, tabB, tabC and tabD. The user will be able to jump between the tabs.
Now to my question:
- tabA, tabB and tabD have single viewControllers
- tabC though has 3 viewControllers - vc1, vc2 and vc3
I am running into issue where the app remembers which viewController the user was in last, and when the user taps tabC, the control goes to the last view controller that the user was in. For example, let's say the following is the sequence:
User taps tabA : view controller for tabA is shown
User taps tabD : view controller for tabD is shown
User taps tabC : view controller vc1 is shown. On tapping some action, the user is taken to vc3
User taps tabB : view controller for tabB is shown
User taps tabC : the vc3 is shown - instead I'd like to show vc1
So far, I have tried the following in vc1 of tabC, but the control does not come to vc1 at all:
- (void) viewWillAppear:(BOOL)animated {
[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:0] animated:YES];
}
How can I tell tabC to always load vc1?
Regards - thanks in advance....
Sam.
Your call to vc1 of tabC likely isn't getting called - viewWillAppear: only gets called when the view will appear on the display.
You might want to look at this function:
- (void)tabBarController:(UITabBarController *)tabBarController
didSelectViewController:(UIViewController *)viewController
(Link to Apple Developer docs)
and this function:
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated
(Link to Apple Developer docs)
If you implement this in your tabBarController delegate, you can act when the user selects tabC, ie:
- (void)tabBarController:(UITabBarController *)tabBarController
didSelectViewController:(UIViewController *)viewController
{
if (viewController == \* tabC view controller */) {
[tabCViewController.navigationController popToRootViewController:YES];
}
}
#dvorak: Thanks for the answer - and sorry to drag on....
I know what I am writing is not an answer - but wanted to show the code that I am working with.
I am not having luck w/ the suggestion. I made the AppDelegate the TabBarControllerDelegate. The callback function gets called - however, using the following code, I am not able to popToRootViewController:
- (void)tabBarController:(UITabBarController *)tbController didSelectViewController:(UIViewController *)viewController {
NSLog(#"ViewController is <%#>", viewController.tabBarItem.title);
if ([viewController.tabBarItem.title isEqualToString:#"tabC"]) {
NSArray *tmp = [viewController.navigationController.tabBarController viewControllers];
[viewController.navigationController popToRootViewControllerAnimated:YES];
}
}
I collected the all ViewControllers in tmp variable , in a hope to see 3 ViewControllers in the array, after visiting all three VCs of tabC. From tabC->vc3, I hit the tabB, and then hit tabC for my exercise. The tmp array had zero elements in the debugger.

Return to first view in UITabBarItem

When I receive a Push Notification, I want to jump to the middle tab on the tabbar and reset the tab (it has multiple table views that the user may have navigated into). I am able to jump to the tab using tabBarController.selectedIndex = 1; ... but how do I reset to the first view?
Implement UITabBarControllerDelegate on a controller class (perhaps your app delegate) and implement tabBarController:didSelectViewController: to pop all pushed view controllers off the navigation stack:
- (void) tabBarController:(UITabBarController *) tabBarController didSelectViewController:(UIViewController *) viewController {
if([viewController isKindOfClass:[UINavigationController class]])
{
[(UINavigationController *)viewController popToRootViewControllerAnimated:YES];
}
}

Disable tab bar navigating to root view

I have a tab bar based application with navigation on each tab bar item.
When i navigate to another view on any tab bar item and click on on tab bar item,then root view controller on that tab bar item is called.
Its like PopToRootView .
Can we disable this situation?
Yes, you can disable the automatic popToRootViewController by implementing the UITabBarControllerDelegate method on your view controller:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController {
if(self.navigationController == viewController) {
return NO;
}
return YES;
}
Thanks to: Disable action - user taps on tabbar item to go to root view controller
Though they say you're not supposed to subclass UINavigationController, you can what you want by making a subclass of UINavigationController and overriding the - (NSArray *)popToRootViewControllerAnimated:(BOOL)animated; method.
Doing this (and not calling the super popToRootViewController) will prevent the view controllers from popping when you click the tab bar item. It could run you into some problems somehow, but hopefully it works for you.
Include UITabBarControllerDelegate in your header file.
try this:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
if(bool_youDontWantPopToRootView)
return (tabBarController.selectedViewController != viewController);
return YES;
}
For bool_youDontWantPopToRootView, you can add condition into it when you want it to behave like default behaviour.
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated; when you pass 'NO' in animated argument you will be directed to root view without any animation
you dont need to use this method while you tap on any tab bar its the default behaviour of the navigation controller that it maintain its own stack of VCs

particular tabbar item hide when app loads in Tab bar controller?

HI,
i have added the following in Appdelegate.m file to hide particular tab bar item("Hai") in tab bar controller(created by IB).but it did not work
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if ([viewController.tabBarItem.title isEqualToString:#"Hai"])
{
self.tabBarController.tabBar.hidden = YES;
}
}
There is no way to hide a tab bar item, but you could create an array of view controllers and exclude this particular one from that array. Later when the tab should be visible, set the view controllers for the tab bar controller again and include that view controller this time.
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated