Question

i have a tab bar based application, with more than 5 tab bar items - so i get 4 of them directly showing in the view and the rest available by selecting the "More" tab. When a tab bar item is pressed, i want to detect which one was it.
So, in the
- (void)tabBarController:(UITabBarController *)tabBarCtrl didSelectViewController:(UIViewController *)viewController method, i use tabBarCtrl.selectedViewController.title to get the item's title.

This works for the tabs visible in the view -that is the 4 first and the "More" tab- but does not work for the rest of my tab bar items which are shown in the list after pressing the "More" tab.

I can see that the didSelectViewController method is not even called when selecting a tab from the "More" list.
How can i detect any of them when pressed?

Thank you in advance.

Was it helpful?

Solution

How to get title of UITabBarItem in the More section?

- (void)tabBarController:(UITabBarController *)tabBarController 
 didSelectViewController:(UIViewController *)viewController
{
    NSLog(@"controller class: %@", NSStringFromClass([viewController class]));
    NSLog(@"controller title: %@", viewController.title);

    if (viewController == tabBarController.moreNavigationController)
    {
        tabBarController.moreNavigationController.delegate = self;
    }
}

OTHER TIPS

You can access the index of selected item by using following code in your UIViewController. It will always return yout tab's index.

self.tabBarController.selectedIndex;

So if you have e.g. 6 items you can go to the "More..." tab, select your "5th" item and selectedIndex will be 4. If you go to the More tab and select 6th item, it'll return 5.


EDIT: If you want to check current position of some UITabBarItem you can do this:

Firstly, in your XIB file you should edit the tag property of each tab, so that 1st tab will have tag = 100, 2nd - 200, 3rd - 300, etc.

Then in ViewController add this code:

UIViewController *selectedVC = [self.tabBarController.viewControllers objectAtIndex:self.tabBarController.selectedIndex];
int selectedItemTag = selectedVC.tabItem.tag;

Then you can determine what viewController is it by using selectedItemTag variable. In this case, you can determine selectedIndex by doint this: selectedIndex = (selectedItemTag-100)/100.

The tag properties are not changed when customizing your UITabBar, so you can trust them :)

You can detect when a tab has been pressed using the UITabBarDelegate methods: http://developer.apple.com/library/ios/#documentation/uikit/reference/UITabBarDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intf/UITabBarDelegate

You can make your UITabBarController class be the delegate and add the method in the implementation:

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item 
{ 
    NSLog(@"tab selected: %@", item.title); 
} 

1. So if you are using a UITabBarController you can make the class implement the UITabBarControllerDelegate and set your UITabBarController delegate to the class that needs to be notified when the TabBar selected item changes, then add the delegate method to your class:

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

Inside this method you can use the UITabBarController selectedIndex property to know which is the current index selected:

-(void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:      (UIViewController *)viewController
{
    NSLog(@"Selected index: %d", tabBarController.selectedIndex);
}

2. If you are not using just the UITabBar you can follow the answer here by Ken Pespisa and iCoder in this post Ken Pespisa and iCoder in this post.

Since you add tags to your EVERY UITabBarItem (even those with index 5 and more).

You can track what tab was selected using following code:

//MARK: - UITabBarControllerDelegate

func tabBarController(tabBarController: UITabBarController, didSelectViewController viewController: UIViewController) {

    if viewController == tabBarController.moreNavigationController {
        tabBarController.moreNavigationController.delegate = self
    } else {
        setSelectedTabBarOption()
    }
}


//MARK: - UINavigationControllerDelegate

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
    setSelectedTabBarOption()
}


private func setSelectedTabBarOption() {

    if let viewControllers = viewControllers {
        let selectedController: UIViewController? = viewControllers.count > selectedIndex ? viewControllers[selectedIndex] : nil
        if let tag = selectedController?.tabBarItem.tag {
            //do whatever with your tag
        }
    }
}
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{

 NSLog(@"Selected index: %d", tabBarController.selectedIndex);

if (viewController == tabBarController.moreNavigationController)
{
    tabBarController.moreNavigationController.delegate = self;
}

NSUInteger selectedIndex = tabBarController.selectedIndex;

switch (selectedIndex) {

    case 0:
        NSLog(@"click tabitem %u",self.tabBarController.selectedIndex);
        break;
    case 1:
        NSLog(@"click me again!! %u",self.tabBarController.selectedIndex);
        break;

    default:
        break;

}

}

If you're using a tab bar controller, you should avoid knowing about the mapping between tab items and view controllers -- that's the job of the tab bar controller. If you're trying to use a tab bar for something else, then you should use UITabBar directly and not use UITabBarController. If you use UITabBar, you can set your own object as the tab bar's delegate, and the delegate will then get messages whenever the selected item changes.

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