How to subclass UIViewController with multiple nibs / xibs? - iphone

I would like to subclass UIViewController with multiple nibs.
For example:
BaseViewController has a nib with a label, and is subclassed from UIViewController
SecondViewController has a nib with a button, and is subclassed from BaseViewController.
SecondViewController should also have the label from the BaseViewController.
I have searched an not found any tutorials on this, only tutorials with ways to add UIView's to UIViewControllers, so I'm not sure this is even possible.
Can anyone explain how to do this, or point me in the direction to the resources that show how to do this (or if it's even possible at all)?

I am using a hierarchy of controllers and it works just fine. As long as your correct match nibs to properties at each level, there is no reason you cannot define parent controllers in a hierarchy.

I don't think that what you are asking can be done. A view can be loaded from only one nib. You could have the base view controller set up with a nib, and descendant view controllers do additional setup in viewDidLoad.

Related

subclassing UIViewController design consideration

So I have five different UIViewController that I would like to create. Each of them has a common thing (an image view on top, a label on top). So I was thinking of creating a parent UIViewController and then have 5 subclass from the parent UIViewController. In this parent view controller it will have the UIImageView, the label, and everything common/shared with the other five. The question is, each of this UIViewController subclass will have it's own nib, however I want it to also have the parent's UIImageView in place. How do I then deal with this?
I guess I am confused if each of the subclass UIViewController has it's own nib, how can I see the parent view controller's xib in this subclass? I know my wording is extremely confusing, I can't seem to find a better way to explain this than this.
Don't create a xib for the parent view controller. Instead, subclassing the parent view controller, then creating a xib for the subclass will expose the IBOutlets from any of the parent classes/view controllers.
Just think of this example, as we've all subclassed UIViewController at some point and created a xib for it, we must connect the main view in the xib to the "view" IBOutlet. We'll that IBOutlet is defined in the UIViewController parent class.

How can I extend UIViewController which is created by XIB?

I have a general view controller (created by XIB) with some common controls. I want to create child view controller which inherits that general view controller. I want use XIB at both parent view and child views. How can I do that?
Answer of your question, although it seems quite vague question -
I want to create child view controller which inherits that general view controller.
you can simply use like - ChildViewController : ParentViewController
I want use XIB at both parent view and child views.
While loading these view controller you can use initWithNibName: bundle: and pass xib here.
See this tutorial that may help you
I think, this is same as you said you want to use same xib for both view controllers. You need to do some work around but don't work this tutorial will show you how do it.

How should I manage swapping a UINavigationController in and out of another UIViewController?

Here's what I have:
A MainWindow.xib file configured with one UIViewController (subclassed to RootViewController). This nib gets loaded at application launch.
RootViewController has two ivars, a custom subclass of UIViewController and a UINavigationController. Both of these are loaded from nibs.
When the application launches both ivars are initialized from their respective nibs, and then the UIViewController.view is added as a subview of RootViewController.view.
Inside UIViewController's view I have a control that triggers an animated swap of UIViewController and UINavigationController. This is where the problem comes in. The swap animates, but the UINavigationController's views are not properly displayed. I get a Navigation Bar with no title, and nothing else.
The UINavigationController nib and underlying functionality have been tested in a stand alone project, but there was no RootViewController.
So, my question is, can I even do this? I've successfully swapped other view controllers like this, but never a UINavigationController. I've seen some documentation that leads me to believe this might be a fools errand, but I haven't convinced myself of that yet.
Solution (Kinda):
I found a solution (workaround? hack?), but it leads to some more questions. I nixed using a Nib for the UINavigationController. Instead, I loaded my UINavigationController's rootViewController from a Nib and then created the UINavigationController programmatically with initWithRootViewController:.
NavRootViewController *navRoot = [[NavRootViewController alloc] initWithNibName:#"NavRootViewController" bundle:nil];
navigationController = [[UINavigationController alloc] initWithRootViewController:navRoot];
[navRoot release];
This works as I expect. Which leads me to the conclusion that the rootViewController property of the UINavigationController wasn't being set properly when I loaded navigationController from a Nib. And the question is, why? Should it?
Also, when you see something like this happening in one case, but not another, it can be beneficial to either create a subclass and make your nib point at that subclass, or if you already have a subclass use that.
In the subclass, override all the various init:, initWithNibName:bundle:, viewDidLoad:, viewWillAppear:, viewDidAppear: and any other appropriate methods, and in those override, just NSLog("") something about which method it is (with param values perhaps) and call the super implementation.
This will give you an observable "track" of which methods are called in which order, and you can set a breakpoint to see where that call comes from.
This will give you enough information to find missing method calls, and then you can pursue the correct problem either here, or through filing a radar or ...
In some cases, viewDidLoad and viewDidAppear or awakeFromNib may need to be called each time you add the UINavigationController back into the stack of UIViewControllers. It seems that when the typical code executes out of your AppDelegate, that the Window, or something behind the scenes is doing something special for UINavigationController that presentModalViewController doesn't do.
I think you may have missed a conceptual point.
A UINavigationController controls view controllers instead of views. It controls when and where view controllers themselves are loaded. The views themselves are loaded only as a side effect of the pushing and popping of their respective controllers.
Therefore, putting a navigation controller inside of a view controller seldom makes much sense.
If I understand what you are trying to do correctly, you should have the RootController actually set as the rootController property of the UINavigationController (yes the nomenclature is extremely confusing.) Then when your swap event occurs, you should have the navigation controller push the next view. The RootController view will disappear to replaced by the other. then you can repeat the process for an arbitrary number of view controllers.
Only in the case of a tabbar would you want a navigation controller to be a property of a view controller. Even then it should be at the top the tab's hierarchy.

Design view in Interface Builder to load lazily in UIViewController

I've managed to get my myself confused... I've got a fairly complex View Controller much of which is developed programatically. I'd like to pop up a "dialog" on top of the view controller at some point and I'd like to "design" that view in Interface Builder because it's fairly straightforward (background UIImageView, some UILabels and a UIButton).
I've created the .xib and am now subclassing UIView with the IBOutlets,etc. I'm now trying to wire it up and realizing I probably need to add an initWithNibName: method so this will instantiate correctly...then I realize that I'm really just making another UIViewController and I don't think we're supposed to have UIViewController views w/in other UIViewController views?!?
So now I'm re-thinking how to go about this "correctly." How best to use IB to design a simple 1/4 screen view that will pop up over a main view?
Call +[NSBundle loadNibNamed:owner:] to load the NIB file that contains your view. If you specify your view controller (i.e., self) as the owner, any connections you make to File's Owner in the NIB file will then be made to the view controller. So you could declare an outlet to your custom view in the view controller and after the call
[NSBundle loadNibNamed:#"MyView" owner:self];
the outlet variable will point to the view object. Alternatively, you can use -[NSBundle loadNibNamed:owner:options:], which returns an array of the top-level objects in the NIB.

Possible to initialize an entire UITableViewController (or subclass) from a secondary NIB... not just a UIView?

Nearly all the UINavigationController examples out there show the use of initWithNibName:bundle: to load a NIB containing NOT an entire UIViewController (or subclass) but just a UIView, with the NIB's File's Owner Class property set to UIViewController (or the appropriate subclass) and its view outlet pointed at the UIView.
Why is this? Why can you not instantiate a full UIViewController (in particular, a UITableViewController) from a secondary NIB? And why do you even need to set the view outlet in IB? I don't understand the point of creating a blank white view which is going to be entirely ignored by a UITableViewController anyway.
In the MainWindow NIB, you can do both of the things that you seemingly can't do from a secondary NIB. You can setup a UINavigationController, and then within that you can setup a UITableViewController (or subclass). And you don't need to create an entirely superflous UIView object - rather helpful, since the whole point (I thought!) of a UITableViewController is that it creates and manages an associated table view for you using its delegate methods.
What is going on here? Am I being stupid? Is there some other way of doing what I want to? Or is there some logical reason for things being the way they are?
In IB create a new "Empty" nib and drag a "Table View Controller" into it from the Library.
Or am I misunderstanding the question?