How to properly use a UITabBarController in Monotouch - iphone

I understand what to do when using a UITabBarController with the MainWindow. But if when I'm in IB and I decide I want to have a UITabBarController, I only ever get a UIViewController that has a UITabBarController. If this is how it needs to be, then when do I .AddSubView of the UITabBarController? In the ViewWillLoad of the UIViewController? Do I just change the class that is inherited from in the code?
Bit lost here.

This is what I do:
derive from UITabBarController in IB
add the new class to my XIB
(if I want to add new tabs outside of IB, I override LoadView in my tab bar controller class and do it in there)
in AppDelegate.FinishedLaunching, I add my tab bar's view as a subview of 'window' (ie window.AddSubview(mainTabBar.View); )
Those steps work for me without any obvious problems.

Related

UIView embedded only in UINavigationController and UITabBarController, why?

In iOS, why can a UIView (and others) be only embedded in a UINavigationController or UITabBarController? What's special about these two classes?
Edit: oops, wanted to ask 'UIViewController' instead of UIView.
No, its not true. UIView is embedded with UIViewController. This class provides life cycle for UIView. It takes responsibility from initializing the view to deallocating the view.
UINavigationController and UITabBarController are just derived from UIViewController. They provide extra functionality for building hierarchy and switching between hierarchy respectively.
UIView can be embedded in any ViewController or its subclass. UINavigationController and UITabbarController are nothing but subclasses of UIViewController.
I think the embedding you're referring to is the embed in menu item which only allows for UITabBarController and UINavigationController. This means that XCode will take your UIViewController subclass and embed it in one of these two controllers. They are special because they are controllers of other controllers (collections of UIViewControllers). Xcode is simply taking some of the pain out of building a view controller and then adding it to a navigation controller or a tab bar. You can easily embed it in one of these with one click and no code. Much easier than in past versions of XCode.
If you're talking about "embed" as in Interface Builder, yes, as of iOS 5, Interface Builder only gracefully designs user interfaces for three view controller containers, UINavigationController, UITabbarController, and UISplitViewController. These are the three container controllers that come out of the box. You can, though, do your own view controller containment. See Session 102 in WWDC 2011 for information on view controller containment. Also refer to the section on view controller containment in the UIViewController Class Reference.

Combining TabBar and Navigation Controllers Question

In my appDelagate I have a UIViewController called "FrontPage" which is basically a log in screen. Once the login has authenticated it removes itself from the superview and creates a tabbarcontroller, navigationcontroller (inside tabbar), and various UIViewControllers in the NC and on their own in the tab bar. I then push my TabBarVC.view to the windows subView.
It works but I was hoping after I set the windows subview to TabBarVC.view I could release the TabBarViewController to dealloc it and the appdelagate would own the TabBarVC, but when I do it's crashing.
As I'm typing this I'm realizing I never pass the actual TabBarVC, just the view but is there a way to do this?
Also if I completely FUBAR'd this up let me know.
You should set the window's rootViewController property to your UITabBarController instance similar to this:
// set the tab bar controller as our root view controller
[self.window setRootViewController:tabBarController];
To clarify, this will add the TabBarController, its view and all of its subviews to the window's view hierarchy for you and I would recommend you use this method for your login view controller as well.
You could make your UITabBarController an IBOutlet to the app delegate (or just keep the code you have that generates it). Make it a retained property of the app delegate, synthesize the property, and either create the UITabBarController in the app delegate (self.tabBarController = ...) or if you use an xib make the IBOutlet connection from the UITabBarController to the app delegate in the xib.
You could add the UITabBarController to the app's window, and then add the FrontPage UIViewController on top of it. Once you remove the FrontPage from the window, the UITabBarController will already be present underneath it.

Changing UIViewController tab bar view to UINavigationController in Xcode 4

I am trying to modify a newly placed UITabBarItem item from a UIViewController to a UINavigationController in XCode 4.
Here is a screenshot of a new view controller called "Near Me" and existing view controllers.
Notice how the new one is a UIViewController, I need this changed to a UINavigationController.
Something as simple as this was easily done in Xcode 3.2 and now that Apple has introduced Xcode 4 - it is just horribly difficult to re-learn this new IDE.
You shouldn't modify a UIViewController to be a UINavigationController. Even though a UINavigationController is a subclass of UIViewController, its job is to manage other View Controllers, not Views.
In IB you should create a UINavigationController and then set the existing UIViewController as the root controller of the new UINavigationController.
You can change it in the menu on the right hand side. Just change the class. I hope this is what you are asking for.
First you create window based application an in that MainWindow.xib file put tabBar Controller. Then delete that two UIView controller and add navigation controller under tabBar Controller. You can see below in screen shot.

How do I create an outlet for additional views?

I'm struggling with the basics on how to build views in Monotouch and how to tie them to C# code.
I know how to create an outlet for an UIViews that are on the Main window. But how can I create an oulet for an UIView that is located on a different view?
The main view has an AppDelegate class I can bind the outlets to. But there's nothing comparable on additional views, even though I chose to create an "Iphone view with Controller".
When you create an "iPhone view with controller", you can open the view controller xib and place your outlets in the UIViewController. So, if you call the new view controller MyViewContoller, you create the outlets on the MyViewController class in interface builder.
MyViewController will be the "File's Owner" in the Interface Builder project window.
Then, you can set up button handlers, etc by overriding MyViewController's ViewDidLoad method.

What is the best way to change my UIViewController to a UINavigationController

I just realised that my 'root' viewController should have been a UINavigationController. Now I want to change this to be a UINavigationController instead and just curious what my best option would be. I built this view and all other views using IB if that makes a different.
I'm mostly worried that I would have to do a lot of copy/pasting and recoding to get everything right or will be it be as easy as manually editing my controller and change the extension to UINavigationController.
Thanks
You do not convert an existing view controller into a navigation controller.
Even though UINavigationController is a subclass of UIViewController, it's task is the management of other view controllers, not the management of views themselves. You don't swap them out one for the other. Instead, you set UIViewControllers to be controlled by the nav.
To add a nav to a project in IB, open the xib and drag over a UINavigationController. Then set the navigation controller's rootControlller property to the existing UIViewController.
And you're done.
You can also "Embed" the Navigation Controller by selecting the View Controller in IB then select Editor->Embed In->Navigation Controller
You can instantiate a trivial not-subclassed UINavigationController and give it your original UIViewController as its root controller, like:
YourRootViewController *rootViewController = [[YourRootViewController] initHoweverYouInitIt];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
and maybe an [rootViewController release];, depending on how you are going to manage memory.
UINavigationController has an 'is-a' relationship with UIViewController, so you should be able to change its class type in Interface Builder with no additional changes.