Nib 的等效情节提要功能

Equivalent Storyboard function for Nib

我正在尝试在 macOS 上转换一个使用 Storyboards 通过委托实例化 ViewController 的项目,尽管我 运行 在尝试将其转换为使用 Nib 时遇到了一些困难反而。

目前代码的情节提要版本使用与两个视图控制器相关联的 App Delegate。单击按钮时,正面 window 会动画并翻转显示另一个(背面)window。实例化视图控制器的代码是:

mainWindow = [NSApplication sharedApplication].windows[0];
secondaryWindow = [[NSWindow alloc]init];
[secondaryWindow setFrame:mainWindow.frame display:false];

// the below is what I'm not sure of - how to reference nib instead of storyboard?

NSStoryboard *mainStoryboard = [NSStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
NSViewController *vc = [mainStoryboard instantiateControllerWithIdentifier:@"BackViewController"];
[secondaryWindow setContentViewController:vc];

我不确定在上面显示的示例中引用 nib 而不是故事板的正确方法。 The project I'm trying to convert is located here。我真的希望有人能帮忙,谢谢!

这很容易做到。只需为两个视图中的每一个制作一个 NSViewController subclass(或者如果你想让它控制整个 window,则制作一个 NSWindowController subclass)。对于每个视图,覆盖 -init 并让它使用视图的 nib 文件的名称调用 super 的 -initWithNibName:bundle: 实现:

@implementation MyViewController

- (instancetype)init {
    self = [super initWithNibName:@"MyViewController" bundle:nil];

    if (self == nil) {
        return nil;
    }

    return self;
}

请注意,如果您需要足够新的 macOS 版本(我认为它是 10.11 或更高版本,但我可能会被一个左右的版本关闭),您不需要甚至必须做这么多,因为 NSViewController 会自动查找与 class.

同名的 nib 文件

无论如何,现在您应该能够实例化一个 MyViewController 并将其视图插入您的视图层次结构中,并像操作任何其他视图一样操作它:

MyViewController *vc = [MyViewController new];

[someSuperview addSubview:vc.view];

如果你想做 windows,你可以做一个 NSWindowController subclass 而不是 NSViewControllerNSWindowController 使用起来有点烦人,因为它的初始化器采用 nib 名称都是 convenience 初始化器,而 designated 初始化器只需要一个 NSWindow。因此,如果您使用的是 Swift,则不能按照我上面使用 NSViewController 的方式进行操作。 Objective-C,当然,通常让你为所欲为,所以你实际上 可以 只调用 super 的 -initWithWindowNibName:owner:,我不会告诉任何人,眨眼眨眼,轻推轻推。但是,为了在风格上正确,您可能 应该 只调用 -initWithWindow: 传递 nil,然后覆盖 windowNibNameowner

@implementation MyWindowController

- (instancetype)init {
    self = [super initWithWindow:nil];

    if (self == nil) {
        return nil;
    }

    return self;
}

- (NSNibName)windowNibName {
    return @"MyWindowController";
}

- (id)owner {
    return self;
}

这应该会给你一个 window 控制器,你可以用 +new(或者 +alloc-init,如果你愿意)初始化,然后调用它的 -window 属性 并正常操作 window。