Nib 的等效情节提要功能

Posted

技术标签:

【中文标题】Nib 的等效情节提要功能【英文标题】:Equivalent Storyboard function for Nib 【发布时间】:2017-11-07 20:28:32 【问题描述】:

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

目前,故事板版本的代码使用与两个视图控制器关联的 App Delegate。当一个按钮被点击时,前窗口动画并翻转显示另一个(后)窗口。实例化视图控制器的代码是:

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];

我不确定在上面显示的示例中引用笔尖而不是情节提要的正确方法。 The project I'm trying to convert is located here。我真的希望有人能提供帮助,谢谢!

【问题讨论】:

【参考方案1】:

这很容易做到。只需为这两个视图中的每一个创建一个NSViewController 子类(或者如果您希望它控制整个窗口,则创建一个NSWindowController 子类)。对于每个视图,覆盖 -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 会自动查找与类同名的 nib 文件。

无论如何,现在您应该能够实例化 MyViewController 并将其视图插入到您的视图层次结构中,并以与操作任何其他视图相同的方式对其进行操作:

MyViewController *vc = [MyViewController new];

[someSuperview addSubview:vc.view];

如果你想改用 windows,你可以创建一个 NSWindowController 子类而不是 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;

这将为您提供一个窗口控制器,您可以使用+new(或+alloc-init,如果您愿意)进行初始化,然后调用它的-window 属性并照常操作窗口。

【讨论】:

以上是关于Nib 的等效情节提要功能的主要内容,如果未能解决你的问题,请参考以下文章

从情节提要加载的 nib 的 Cocoa replaceSubview

Xcode,从情节提要中提取视图到笔尖,最好的方法?

无法使具有标识符 Cell 的单元出队 - 必须为标识符注册一个 nib 或一个类,或者在情节提要中连接一个原型单元

无法将具有标识符 TodoItemRow 的单元格出列 - 必须为标识符注册一个 nib 或一个类,或者连接情节提要中的原型单元格

在笔尖而不是情节提要中制作原型单元

如何在 nib 中为 UIView 应用自动布局?