Reputation: 21
I need to have a view which will contain controls like sliders and buttons, and have a colored background. I am unsure whether to subclass NSView
or NSViewController
. I thought I could subclass an NSView
and draw a custom background and layout the controls in a xib, and set the outlets to the NSView
subclass.
Some buttons need to toggle, eg a Play/Pause button, I thought this logic should be done in the NSView
, and NSViewController
be notified when the button toggles, rather than the NSViewController
having to manage the toggle it self.
But when I go to create a NSView
subclass the option to create a xib
is greyed out, it is only possible with an NSViewController
. So do I have to have the outlets on the NSViewController
?
I wanted myView.playPauseButton
, but it seems I have to have myViewController.playPauseButton
?
Upvotes: 2
Views: 2354
Reputation: 69037
I need to have a view which will contain controls like sliders and buttons, and have a colored background. I am unsure whether to subclass NSView or NSViewController. I thought I could subclass an NSView and draw a custom background and layout the controls in a xib, and set the outlets to the NSView subclass.
If you want to use a xib, you have to go with a NSViewController
subclass; that's what it is for, among other things.
In general, for what you are trying to do (bundling several controls together), NSViewController
is the class to use.
You can also see this from the point of view of the Model-View-Controller pattern (that is where view controllers and views come from): the view has to do with how things appear; the controller has to do with user interaction (and interaction with the model).
You could certainly define a NSView
subclass and define its content, either programmatically or in IB (adding the slider and the buttons as subviews to it), but I don't see much advantage to it, unless you are going to provide a kind of specific control.
EDIT:
You state in a comment that you would like use use your custom, IB-defined NSView
inside of a NSSplitView
. This makes things a bit more contextualized.
Now, as usual there are many design options, e.g., you might define your own MySplitController
allowing you to specify the nibs from which the split view's subviews should be loaded.
But, if I understand your aim correctly, what you would like to do is defining an NSView in a xib and have it used within an NSSplitView, like if it were one of the default views types that IB allows.
This was allowed by Interface Builder Plug-ins. Unfortunately, they seem to be not supported anymore in Xcode 4.
Then the only option I see is to define a subclass of NSView
, e.g., MyCustomView
and then in its initWithFrame:
method load the xib file, identify the view you defined in it, and adding it as a subview.
Specifically, you can use this code to load the xib files top level objects, among which your custom view will be found:
NSNib *nib = [[[NSNib alloc] initWithNibNamed:@"MyView" bundle:nil] autorelease];
NSArray *topLevelObjects;
if (![nib instantiateWithOwner:customViewOwner topLevelObjects:&topLevelObjects]) {
//- handle error
}
MyView *myView = nil;
for (id topLevelObject in topLevelObjects) {
if ([topLevelObject isKindOfClass:[MyView class]) {
myView = topLevelObject;
break;
}
}
To simplify things, you can have this xib file only define your custom NSView and the ubiquitous File's Owner (which is the link to integrating the view into the rest of your app).
As you see, I am passing a customViewOwner
to instantiateWithOwner
: this would be your main view controller or app delegate in charge for responding to all actions coming from the custom view and to set its state when required. This class would be the file owner of your xib, so to have a really modular design, it would be better to define your MyCustomViewController
that you subclass in specific projects.
Once you have defined such a custom NSView subclass, then the only thing you need to do to integrate it into your NSSplitView is setting the NSSplitView's subviews Class to MyCustomView
.
This is not as straightforward as using an IB plug-in, but it can serve well the purpose of integrating views defined in different xib files.
Upvotes: 3
Reputation: 434
Its best to subclass NSViewController and init with a xib or layout your subviews manually in code. From my experience, subclassing NSView has never worked out the way I've wanted it too, including the implementation you're looking for.
Upvotes: -1