4
votes

I have a MyCustomView subclassed from NSView designed in a .xib.

I would like to insert this view into some of my other xib's round my application. How should I do this? If i drag a custom view and change the class to MyCustomView, but that does not load my xib-file. Can this only be done programmatically or is there a way to do this inside interface builder?

EDIT1:

Here is a very small demo-project: http://s000.tinyupload.com/index.php?file_id=09538344018446482999

It contains the default MainMenu xib and my CustomView xib. I would like my CustomView.xib to be displayed inside the custom view added to my MainMenu.xib -- using as less code as possible.

4

4 Answers

6
votes

For loading the view you need to add on your window:- Created custom class of view inheriting to NSViewController

#import <Cocoa/Cocoa.h>

@interface NewViewController : NSViewController

@end

#import "NewViewController.h"

@implementation NewViewController

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Initialization code here.
    }

    return self;
}

@end

Your xib name is yourview.xib

- (void)windowDidLoad {
    NSViewController *yourVC = [[NewViewController alloc] initWithNibName:@"NewViewController" bundle:nil];
    [[[self window] contentView] addSubview:[yourVC view]];
}
0
votes

Sounds like you need a container view. But I think you will have to use storyboard for it to be doable in interface builder.

0
votes

Use a view controller as it will handle nib loading for you and provide a place to hook up IBOutlet and IBActions in a reusable way.

In your app delegate or whatever controller create an instance of your view controller. Ask your view controller to load its view. Cast the return type to your view class name. Then keep a reference to your view controller and possibly the view.

Tell whatever view to add your view as a subview. Add any layout constraints. ( you can build out very generic constraints to add themselves in your view or view controller by overriding viewDidMoveToSuperview or viewDidMoveToWindow when superview or window are not nil. Use the same to remove your constraints. )

Oddly you remove a view by telling it to remove itself from its superview.

-1
votes

I'd advise just doing it programmatically:

  1. Add a View to your main xib/storyboard and set the custom class to your custom view's class
  2. In your xib for your custom view, set the File's Owner class to your custom view's class
  3. Hook up any IBOutlets, etc. as needed
  4. Make a __strong property/ivar for holding a reference to the top level NSView of the xib
  5. Implement initFromFrame in your custom view's class roughly as follows:
@interface CustomView ()
{
    __strong NSView *nibView;
}
@end

@implementation CustomView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        NSArray *nibObjects;
        [[NSBundle mainBundle] loadNibNamed:@"CustomView" owner:self topLevelObjects:&nibObjects];
        nibView = nibObjects[1];
        [self addSubview:nibView];
    }
    return self;
}

The IBOutlet are connected up immediately after the loadNibNamed call, so you can do further initialization from there.

Another option is to do things purely programmatically: 1. In your custom xib, set the root View's class to your custom class 2. Implement awakeFromNib in your custom class to perform initialization 3. Call loadNibNamed: on your custom xib and programmatically add it to the user interface without interface builder.