I'd like to set up a custom NSView in Interface-Builder, but I don't get it to work for OSX.
In my ViewController's .xib, I added a custom view and set the Class to MyCustomView. I created MyCustomView.h, MyCustomView.m and MyCustomView.xib.
In MyCustomView.xib, I set the Class to MyCustomView as well. In MyCustomView.m, - (void)awakeFromNib
is called, but - (id)initWithCoder:(NSCoder *)aDecoder
and - (id) awakeAfterUsingCoder:(NSCoder*)aDecoder
aren't.
What I'd like to achieve is that in my ViewController, the view I added is "filled" with the view I set up in MyCustomView.xib. What's the best way to do that?
EDIT: I don't think I was clear enough...
I've got my ViewController containing a Custom View called MyCustomView.
This view should be of type MyCustomView, where
MyCustomView.h MyCustomView.m MyCustomView.xib
exists. I already set the File's Owner of MyCustomView.xib to MyCustomView and I already set the CustomView in my ViewController to MyCustomView - but it doesn't work.
If I do it with
- (void)awakeFromNib {
NSString* nibName = NSStringFromClass([self class]);
NSArray* topLevelObjects;
[[NSBundle mainBundle] loadNibNamed:nibName
owner:nil
topLevelObjects:&topLevelObjects];
NSView* view = topLevelObjects[0];
[view setFrame:[self bounds]];
[self addSubview:view];
}
I only get a view of type NSView, not MyCustomView... Is there no easy way to tell the ViewController.xib that it's a MyCustomView?
EDIT 2: I uploaded a simple project
At https://dl.dropboxusercontent.com/u/119600/Testproject.zip you find a simple project with the MyCustomView (not in a ViewController but in the window.xib) - but it doesn't show the button which is in MyCustomView.xib. I'd like to achieve exactly that - what's the simplest, best way?
EDIT - apologies, my existing answer failed to take into account the need to connect outlets and actions. This way should do it...
Given the files...
MyCustomView.h
MyCustomView.m
MyCustomView.xib
In MyCustomView.h
declare IBOutlets for your interface elements. You need at least one, to hold a pointer to the top-level view in the xib file
@property (nonatomic, strong) IBOutlet NSView *view;
In MyCustomView.xib
NSView
class.view
outlet.In MyCustomView.m:
- (id)initWithFrame:(NSRect)frame
{
NSString* nibName = NSStringFromClass([self class]);
self = [super initWithFrame:frame];
if (self) {
if ([[NSBundle mainBundle] loadNibNamed:nibName
owner:self
topLevelObjects:nil]) {
[self.view setFrame:[self bounds]];
[self addSubview:self.view];
[self.myCustomButton setTitle:@"test success"];
}
}
return self;
}
In your window's xib file, add a custom NSView and change it's class to MyCustomView.
in OSX prior to 10.8 the method loadNibNamed
was a class method - use it instead if you need backwards compatibility, but it is deprecated now:
[NSBundle loadNibNamed:@"NibView" owner:self]
Note that MyCustomView.xib's view is NOT MyCustomView's view, but the sole subview of it's view (this is similar to the way a tableViewCell possesses a single contentView).
In the project sample you have posted, you need to make the following changes:
in MyCustomView.h
. add an NSView property
in MyCustomView.xib:
. change the top-level view from MyCustomView
custom class to NSView
(the default)
. set the File's Owner to MyCustomView
.
. connect IBOutlets from File's owner's view
and myCustomButton
to interface view and button
. for testing make the view a lot smaller and push the button up to the top right (you won't see it in your window as it is here)
in MyCustomView.m:
. replace all of your implementation code with the initWithFrame
method here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With