Reputation: 13062
I am building a cocoa application with one main window controller with a xib. That xib contains many custom view classes. I would like to add an NSViewController to the xib, but i'm running into some trouble.
In interface builder I can drag the NSViewController into the xib, assign it its custom controller class, and assign its view to the appropriate view in the xib. Here's the problem: neither the initWithNibName:Bundle:
or loadView
get called.
What am I missing?
EDIT: People seem to be misunderstanding the question so I'll clarify.
The window already has a view controller. What I am seeking to do is assign separate view controllers to several of the subviews. I need to know how to associate my NSViewController
subclass with the appropriate NSView
subclass (which is a child of the main window).
Or in other words, I am trying to use multiple NSViewController
subclasses to controll many different custom views (one each) within a single .xib file. Those controllers and subviews have their own .xibs which should ultimately become visible in the same window.
Upvotes: 0
Views: 1378
Reputation: 4797
I used to get stuck with that as well and gave up on that thing - the blue circle with a white bordered view in it from the IB palette. I now create my controllers from code and only set a reference in IB to the owning controller class via the file owner: right click the file owner, enter the class name in the Identity inspector and then make a connection from the file's owner view to the view.
In your code you then do at an appropriate initialisation point:
[self setMyViewController = [[MyViewController alloc] initWithNibName: @"MyView" bundle: [NSBundle mainBundle]]
For your specific case this could be in windowDidLoad
method when your window is loaded from its nib and ready for work. You can then add the view to your windows content view. Also you might want to consider to have a 1:1 relation between view and view controller. It makes life a lot easier in terms of maintenance.
EDIT: Like @pcperini suggests in his comments you can use the palette component, but you'll still need to instantiate the controller in your code. If you want to use the palette component, create a property in your main controller or AppDelegate:
@property (...) MyViewController *myViewController;
Add the line of code to actually create the controller (see above). Then, using the bindings inspector bind the palette component to the myViewController
property.
So, what you are missing is that you are actually not instantiating the controller object.
EDIT 2: Here's the code (the awakeFromNib is the method of the top controller). It creates two child controllers each handling a different subview:
- (void) awakeFromNib {
[[self startEndTopicHeader] setHeader: @"Event timeline boundary"];
[[self startDateHeaderView] setHeader: @"Event (start) date"];
[[self endDateHeaderView] setHeader: @"Event end date"];
[self setStartDateViewController: [[EventTimeViewController alloc] initWithNibName: @"EventTimeView" bundle: [NSBundle mainBundle]]];
[[[self startDateViewController] view] setFrame: [[self dummyStartView] bounds]];
[[self dummyStartView] addSubview: [[self startDateViewController] view]];
[[self startDateViewController] setParentController: self];
[self setEndDateViewController: [[EventTimeViewController alloc] initWithNibName: @"EventTimeView" bundle: [NSBundle mainBundle]]];
[[[self endDateViewController] view] setFrame: [[self dummyEndView] bounds]];
[[self dummyEndView] addSubview: [[self endDateViewController] view]];
[[self endDateViewController] setParentController: self];
}
Upvotes: 0
Reputation: 2526
The pattern I use for NSViewController is to have a xib per view controller. Then, when you need that view controller you alloc
it and use the initWithNibName:Bundle:
method. As soon as you use its view, loadView
will get called.
Example:
self.editViewController = [[[MyEditViewController alloc] initWithNibName:@"MyEditViewController" bundle: nil] autorelease];
[self.window setContentView: editViewController.view];
Upvotes: 1