简体   繁体   English

Interface Builder:如何从nib文件加载视图

[英]Interface Builder: How to load view from nib file

I have a MyCustomView subclassed from NSView designed in a .xib. 我有一个在.xib中设计的NSView的MyCustomView子类。

I would like to insert this view into some of my other xib's round my application. 我想将这个视图插入到我的其他一些xib的应用程序中。 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. 如果我拖动自定义视图并将类更改为MyCustomView,但不加载我的xib文件。 Can this only be done programmatically or is there a way to do this inside interface builder? 这只能以编程方式完成,还是有办法在界面构建器中执行此操作?

EDIT1: EDIT1:

Here is a very small demo-project: http://s000.tinyupload.com/index.php?file_id=09538344018446482999 这是一个非常小的演示项目: http//s000.tinyupload.com/index.php?file_id = 09538344018446482999

It contains the default MainMenu xib and my CustomView xib. 它包含默认的MainMenu xib和我的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. 我希望我的CustomView.xib显示在添加到MainMenu.xib的自定义视图中 - 使用尽可能少的代码。

For loading the view you need to add on your window:- Created custom class of view inheriting to NSViewController 要加载视图,需要在窗口中添加: - 创建继承到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 您的xib名称是yourview.xib

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

Sounds like you need a container view. 听起来你需要一个容器视图。 But I think you will have to use storyboard for it to be doable in interface builder. 但我认为你必须使用故事板才能在界面构建器中使用它。

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. 使用视图控制器,因为它将为您处理笔尖加载,并提供一个以可重用的方式连接IBOutletIBActions的位置。

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. ) (你可以打造出非常通用的限制通过重写添加自己在您的视图或视图控制器viewDidMoveToSuperviewviewDidMoveToWindow时, superview或窗口不为零。使用同一删除您的约束。)

Oddly you remove a view by telling it to remove itself from its superview . 奇怪的是,你通过告诉它从superview删除一个视图来删除它。

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 将视图添加到主xib/storyboard并将自定义类设置为自定义视图的类
  2. In your xib for your custom view, set the File's Owner class to your custom view's class 在您的自定义视图的xib中,将File的Owner类设置为自定义视图的类
  3. Hook up any IBOutlets , etc. as needed 根据需要连接任何IBOutlets
  4. Make a __strong property/ivar for holding a reference to the top level NSView of the xib 创建__strong属性/ ivar以保存对xib的顶级NSView的引用
  5. Implement initFromFrame in your custom view's class roughly as follows: 在自定义视图的类中实现initFromFrame大致如下:
@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. IBOutletloadNibNamed调用之后立即连接,因此您可以从那里进行进一步的初始化。

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. 另一种选择是纯粹以编程方式执行操作:1。在自定义xib ,将根View的类设置为自定义类2.在自定义类中实现awakeFromNib以执行初始化3.在自定义xib上调用loadNibNamed:并以编程方式将其添加到没有界面构建器的用户界面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM