Overriding UITabBarController behavior

Discussion in 'iOS Development' started by jbonedev, Jul 1, 2009.

  1. jbonedev

    jbonedev New Member

    Joined:
    May 24, 2009
    Messages:
    44
    Likes Received:
    0
    Device:
    iPhone 3G (Black)
    When a UITabBarController tab is currently focused (selected) and user clicks on the already selected tab again, it pops all of that tab's ViewControllers back to root. WTF?
    I need to prevent this.

    I've tried subclassing UITabBarController and overriding the touchesBegan message to intercept these touches and not pass them on to the superclass, but that doesn't work. I never notice the touchesBegan is ever being called based on log messages.

    Any tips on how to extend UITabBarController to accomplish this? (Or some other mechanism to accomplish the same?)

    Thx for any tips.
  2. Cyanidepoison

    Cyanidepoison Active Member

    Joined:
    Jan 18, 2008
    Messages:
    1,076
    Likes Received:
    2
    You shouldn't do that, that behavior is part of the iPhone OS and is something that users expect to happen. They expect that when they hit an already selected tab it takes them "home" in that tab. Look at all the applications on the iPhone that use tab bars, they all behave that way for a reason.
  3. jbonedev

    jbonedev New Member

    Joined:
    May 24, 2009
    Messages:
    44
    Likes Received:
    0
    Device:
    iPhone 3G (Black)
    Hm. What is the expected behavior if the user edits a bunch of info in the pushed views? Does the user expect all of that data to be discarded?

    Ideally I'd like a popup here asking something like "quit without saving?" Yes/No. But that seems equally difficult to implement.
  4. Cyanidepoison

    Cyanidepoison Active Member

    Joined:
    Jan 18, 2008
    Messages:
    1,076
    Likes Received:
    2
    -viewWillDisappear should be called.
  5. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,642
    Likes Received:
    129
    There is no reason to subclass the UITabBarController. Also, what you're describing is NOT the default behavior of a UITabBarController. Clearly, you are either doing something wrong, or you do not fully understand what you are doing and you actually have a call to pop to the root view controller (extremely likely).
  6. Cyanidepoison

    Cyanidepoison Active Member

    Joined:
    Jan 18, 2008
    Messages:
    1,076
    Likes Received:
    2
    If it isn't the default behavior, why does every application on my iPhone work that way?
  7. jbonedev

    jbonedev New Member

    Joined:
    May 24, 2009
    Messages:
    44
    Likes Received:
    0
    Device:
    iPhone 3G (Black)
    This doesn't provide the user any way of cancelling the operationthough. So I can choose to save the data overwriting the original but that might not be what the user wants. The user needs to be remnded that they changed the data and given the option to save or abandon their changes. How do I achieve this?
  8. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,642
    Likes Received:
    129
    That would be because the programmers make it work that way. After all, as the above poster pointed out, it is what the user expects. Also, there is a real benefit to popping view controllers that you are not currently using.

    One major example if an app thy doesn't pop view controllers when another tab is pressed is Facebook. There are literally just as many apps that don't pop as there are apps that pop.

    Trust me, I've been working with UITabBarControllers since the 2.0 beta SDKs.

    Also, apps such as my soon to be released photo booth like application would cease to work if the default tabbar behavior was to operate how you think it is supposed to work.

    The sole purpose of a UITabBarController is to serve as a view controller that has a bar consisting of up to five buttons that each present a sub view controller. It is completely clueless as to what type of view controller it switches to, as it should be. The sub view controllers can be any view controller or subclass of, UIViewController, UITableViewController, UIImagePicker..., PLPhoto..., MPMedia..., or even a UINavigationController.

    For the UITabBarController to have specific code and functions based on each type of view controller is a ridiculous notion that breaks the principals of OOP. Also, if you subclass any type if view controller then those functions would break and cease to work, as you're using a different type of controller then the superclass.

    It is solely the navigation controller's responsibility to monitor its own stack, as it should be.

    Test, create a new tab based project. Create a UINavigationController and a UIViewController. Add that navigation controller as a tab. Now add a button to your view controller's view that pushes another instance of itself to the navigation stack. Crete another tab an put anything you want in it. Run the app and push the view controllers a bunch of times. now switch to the other tab and go back to th nav controller tab. You'll notice that it did not pop.

    I also believe in one of my InterfaceBuilder/Xcode tutorials, a poster added a question asking how to get the navigation stack to pop when another tab is selected. That would be further proof that the default behavior is to do nothing (ie, not to pop).


    Please ignore any typos, I type this out on my phone.
  9. jbonedev

    jbonedev New Member

    Joined:
    May 24, 2009
    Messages:
    44
    Likes Received:
    0
    Device:
    iPhone 3G (Black)
    Does this apply to cases when you select the currently selected tab? I.e. re-select a tab which has several levels of pushed view controllers on it's stack?
  10. SkylarEC

    SkylarEC Super Moderator Emeritus Staff Member

    Joined:
    Sep 19, 2007
    Messages:
    6,642
    Likes Received:
    129
    Alright, you got me there. I guess I should have spoken more in generalizations. Reselecting a tab will make the nav stack pop. So the tab bar does have an idea if what's in it. Likewise, a navigation controller knows if it's in a tab bar controller.

    If you want data to save, override the viewWillDisappear, or whatever of the viewcontroller that is currently displayed. If it isn't being called, then you will need to override the UINavigationController delegate methods (<UINavigationControllerDelegate>).

    If you don't want the nav stack to pop when it is reselected, go into your tab controller delegate object and override the UITabBarController delegate methods to do nothing if the current view controller is tje same as tje selected view controller.

Share This Page