【问题标题】:Equivalent Storyboard function for NibNib 的等效情节提要功能
【发布时间】: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。我真的希望有人能提供帮助,谢谢!

【问题讨论】:

    标签: objective-c xcode macos nswindow nib


    【解决方案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 属性并照常操作窗口。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      • 2015-06-30
      • 2023-03-10
      • 2015-12-10
      • 2013-08-16
      相关资源
      最近更新 更多