views:

570

answers:

2

Here is my problem:

I've read a lot about how to use a tab bar within a navigation based application, but i still can't figure it out. I have tried both to use and avoid using a tab bar controller, but i just can't find the solution.

I already have a navigation based app working. I have several nib files (views), each one with its own view controller, that i programmatically push onto the navigation controller stack. I need one of this views to have a tab bar that allows me to switch between some of the others. I understand how the tab bar works, and i do think what i need is to use a tab bar controller, since it would allow me to define the view controllers associated with each tab bar item, and manage all about them. However, i can't see how to do it.

If i do declare a tab bar controller in my "tabBarViewController", draw the tab bar controller in my "tabBarView" and link them with the IB, it will give me an error (I reckon this is because i haven't really pushed the tab bar controller's view? do i need something equivalent to "[window addSubView:[tabbarcontroller view]]?). In this case, all i need to know is how to "see" the tab bar controller's top view controller's view within a view controller i have already pushed.

If i try not to use a tab bar controller, as i have read is the best solution to this problem, ¿how do i manage tab bar items, the switchs between them, etc?

I would really appreciate your help.

A: 

You can't push a tab bar controller onto a navigation controller stack. There's just no supported way to do it.

What you may want to consider instead is creating your own instance of UITabBar, then using a delegate that conforms to UITabBarDelegate. That way, your delegate will receive the tabBar:didSelectItem: message whenever a tab bar item is selected by the user. You'll have to manage the NSArray of items for the bar yourself, though, without using IB.

Once you've got that figured out, all that's left to do is push a regular UIViewController onto your navigation stack like any other, and just have that controller manage your tab bar and delegate.

Tim
You are wrong - you can push a tab bar onto a nav stack. I just wrote a test project that does exactly that and it works fine.
jsd
That's incorrect. A UITabBarController is a subclass of a UIViewController, and `-[UINavigationController pushViewController:animated:]` only needs a UIViewController object to push. So you can push a UINavigationController onto a UINavigationController if you wanted.
Dave DeLong
@jsd - the View Controller Programming Guide for iPhone OS begs to differ (specifically, in the section Combining Tab Bar and Navigation Controllers). http://developer.apple.com/iphone/library/featuredarticles/ViewControllerPGforiPhoneOS/CombiningToolbarandNavigationControllers/CombiningToolbarandNavigationControllers.html
Tim
@Tim - you're right, it does say you should "never" do that, although it doesn't explain why. Perhaps I will file a documentation bug...
jsd
@jsd - it may be because that allows the situation where you could have a navigation controller that contains a tab bar controller that itself contains a navigation controller. It could be pretty difficult to define expected behavior in that context.
Tim
So, as i thought, a solution would be not using a tabbarcontroller, but a delegate (child class of tabbarcontroller?tabbardelegate?) "linked" to my tabbar instance? Could you give me some tips (or some code) about how to do this? Thank you
Carlos
@Carlos - the `delegate` object can be any class, so long as it implements the UITabBarDelegate protocol. I'd suggest either creating a custom class for the delegate or making an existing UIViewController (perhaps the one containing the tab bar) the delegate. See http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UITabBarDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intf/UITabBarDelegate
Tim
@Tim Thank you very much for your help. I will try to implement your solution, though there are some concepts i don't fully understand. Again, thank you.
Carlos
A: 

You can do this with a bit of code, like so:

FooViewController *foo = [[FooViewController alloc] init];
BarViewController *bar = [[BarViewController alloc] init];

UITabBarController *tabby = [[UITabBarController alloc] init];
[tabby setViewControllers:[NSArray arrayWithObjects:foo, bar, nil] animated:NO];
[self.navigationController pushViewController:tabby animated:YES];
[foo release];
[bar release];
[tabby release];

You could probably do it with IB as well, just load the tab bar controller from a nib.

I built a sample project that demonstrates this in action, you can download it from http://s3.thismoment.com/navtab.zip

jsd