Nib的等效故事板功能

时间:2017-11-07 20:28:32

标签: objective-c xcode macos nswindow nib

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

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

double CustomRound(double x) => Math.Ceiling(x * 10000) / 10000;

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

1 个答案:

答案 0 :(得分:1)

这很容易做到。只需为两个视图中的每个视图创建一个NSViewController子类(或NSWindowController子类,如果您希望它控制整个窗口)。对于每个视图,覆盖-init并让它调用-initWithNibName:bundle:的超级实现,并使用视图的nib文件名称:

@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子类而不是NSViewController。使用NSWindowController会稍微烦一些,因为它的nib名称的初始化程序都是便利初始化程序,而指定的初始化程序只需要NSWindow 。因此,如果您正在使用Swift,那么就不能按照上面NSViewController的方式进行操作。当然,Objective-C通常会让你做任何你想做的事情,所以你实际上可以通过调用超级-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属性并进行操作窗户正常。