views:

12507

answers:

8

I'm trying to implement a UI structured like in the Tweetie app, which behaves as so: the top-level view controller seems to be a navigation controller, whose root view is an "Accounts" table view. If you click on any account, it goes to the second level, which has a tab bar across the bottom. Each tab item shows a different list and lets you drill down further (the subsequent levels don't show the tab bar).

So, this seems like the implementation hierarchy is:

  • UINavigationController
    1. Accounts: UITableViewController
    2. UITabBarController
      1. Tweets: UITableViewController
        • Detail view of a tweet/user/etc
      2. Replies: UITableViewController
      3. ...

This seems to work[^1], but appears to be unsupported according to the SDK documentation for -pushViewController:animated: (emphasis added):

viewController: The view controller that is pushed onto the stack. It cannot be an instance of tab bar controller.

I would like to avoid private APIs and the like, but I'm not sure why this usage is explicitly prohibited even when it seems to work fine. Anyone know the reason?

I've thought about putting the tab bar controller as the main controller, with each of the tabs containing separate navigation controllers. The problem with this is that each nav controller needs to share a single root view controller (namely the "Accounts" table in Tweetie) -- this doesn't seem to work: pushing the table controller to a second nav controller seems to remove it from the first. Not to mention all the book-keeping when selecting a different account would probably be a pain.

How should I implement this the Right Way?

[^1]: The tab bar controller needs to be subclassed so that the tab bar controller's navigation item at that level stays in sync with the selected tab's navigation item, and the individual tab's table controller's need to push their respective detail views to self.tabBarController.navigationController instead of self.navigationController.

A: 

I too have wondered about that requirement.

The easiest way is get the desired effect (and stay within the SDK guide) is to push on a plain UIViewController that itself contains the UITabBarController.

Andrew Grant
I've tried that and found that the tab bar became unresponsive - any time the tab bar controller is not the immediate child of the window itself it seems
Rob Fonseca-Ensor
+5  A: 

It's possible to add a UITabBar to any UIViewController. That way you don't actually have to push a UITabBarController and therefore stay within the guidelines of the Apple API.

In interface builder UITabBar is under "Windows, Views & Bars" in the Cocoa Touch Library.

DasBoot
+3  A: 

I do this in a couple of my apps. The trick to adding a tab bar to a navigationController based app is to NOT use a TabBarController. Add a Tab Bar to the view, make the view controller for that view a TabBarDelegate, and respond to user selections on the tab bar in the code of the view controller.

I use Tab Bars to add additional views to the Tab Bar's view as sub-views, to reload a table view with different datasets, to reload a UIPickerView, etc.

Alpinista
+19  A: 

The two previous answers got it right - I don't use UITabBarController in Tweetie. It's pretty easy to write a custom XXTabBarController (plain subclass of UIViewController) that is happy to get pushed onto a nav controller stack, but still lives by the "view controller" philosophy. Each "tab" on the account-specific view (Tweets/Replies/Messages) is its own view controller, and as far as they are concerned they're getting swapped around on screen by a plain-ol UITabBarController.

atebits
I hadn't thought of using a tab bar without a UITabBarController. Thank you, and the previous answerers, for the insight!
Daniel Dickison
+1  A: 

does anyone have any source code or a tutorial showing how to do this explicitly? i'm trying to figure it out on my own but not getting anywhere.

See: http://paste.lisp.org/display/76358The objects are instantiated in a XIB file which isn't shown but should be self-explanatory. You can push instances of TabController onto any navigation controller.For some reason, though, setting tabBar.selectedItem isn't working...
Daniel Dickison
A: 

Thank you. Will keep in mind.

Brian
This is a question, not an answer.
Michael Myers
This site is not like a forum. It's a question and answer site. You ask pointed and concise questions and get responses.
MunkiPhD
+8  A: 

I'm building an app that uses a similar navigation framework to Tweetie. I've written a post about how to do this on my blog www.wiredbob.com which also links to the source code. It's a full template you could take and use as a basis for another project. Good luck!

Robert Conn
The source code you have provided is a great reference - thanks!
barfoon
Really Helpful Source Code and Tutorial.
Louis Russell
For those wondering, the link to the mentioned blog post is http://www.wiredbob.com/blog/2009/4/20/iphone-tweetie-style-navigation-framework.html
QAD
+2  A: 

I was struggling for the past hour to implement a UITabBar because it would get hidden when I tried to display my view; then I found this post:

http://discussions.apple.com/thread.jspa?threadID=2099944&tstart=0

Basically, make sure you insert your new view below the tabbar, per this line of code:

[self.view insertSubview:tab2ViewController.view belowSubview:myTabBar];

esilver