【问题标题】:Binding a window created with the Cocoa Interface builder to a programmatically created one将使用 Cocoa 界面构建器创建的窗口绑定到以编程方式创建的窗口
【发布时间】:2013-10-28 15:17:23
【问题描述】:

我有一个 Objective C 应用程序,它首先加载使用 Interface Builder 创建的窗口:

//in main()
[NSApplication sharedApplication];
[NSBundle loadNibNamed:@"MainMenu" owner:NSApp];
[NSApp run];

在 MainMenu.xib 我有一个带有按钮的窗口。我想在按下该按钮时以编程方式创建第二个窗口。

  //in MainMenu.xib Controller.h
  @class SecondWindowController;

  @interface Controller: NSWindowController {
     @private
     SecondWindowController *sw;
  }
  - (IBAction)onButtonPress:(id)object;
  @end

//in MainMenu.xib Controller.m
#import "SecondWindowController.h"

@implementation Controller
- (IBAction)onButtonPress:(id)object {
  sw = [[SecondWindowController alloc] initWithWindowNibName:@"SecondWindow"];
  [sw showWindow:self];
  [[self window] orderOut:self];
}
@end

SecondWindowController 继承自 NSWindowController。在 SecondWindowController.h 我有:

- (id)initWithWindow:(NSWindow*)window {
  self = [super initWithWindow:window];
  if (self) {
    NSRect window_rect = { {custom_height1, custom_width1}, 
                           {custom_height2,    custom_width2} };
    NSWindow* secondWindow = [[NSWindow alloc] 
                         initWithContentRect:window_rect
                         styleMask: ...
                         backing: NSBackingStoreBuffered
                         defer:NO];                         
  }
  return self;
}

在 SecondWindow.xib 中我什么都没有。当第一个窗口的按钮被按下时,第一个窗口消失并且应用程序关闭。我不想为第二个窗口使用界面生成器的原因是我想以编程方式初始化它。这可能吗?如果可以,实现这一目标的正确方法是什么?

【问题讨论】:

  • 第二个窗口控制器必须是一个实例变量,这样它才不会超出onButtonPress: 的范围。
  • 对不起,是的,我忘了说……
  • SecondWindow.xib 中没有窗口对象,我想我应该在代码中创建窗口。我应该添加一个吗?
  • 不,看我的回答。我被你矛盾的代码和要求弄糊涂了……

标签: objective-c cocoa


【解决方案1】:

好的,我最初对您使用 initWithWindowNibName:@"SecondWindow" 感到困惑,它会尝试从 NIB 文件加载窗口,您稍后提到您不想这样做。

请使用它来创建您的窗口:

- (IBAction)onButtonPress:(id)object {
    if (!sw)
        sw = [[SecondWindowController alloc] init];
    [sw showWindow:self];
    [[self window] orderOut:self];
}

这将避免创建您不想要的窗口控制器的多个副本(如果您这样做,那么您需要将它们存储在一个数组中)。注意名称sw 按照惯例是不正确的;使用_sw 或创建setter/getter 方法并使用self.sw

像这样初始化SecondWindowController

- (id)init {
    NSRect window_rect = NSMakeRect(custom_x, custom_y,
                                    custom_width, custom_height);
    NSWindow* secondWindow = [[NSWindow alloc] 
                         initWithContentRect:window_rect
                         styleMask: ...
                         backing: NSBackingStoreBuffered
                         defer:NO];                         

    self = [super initWithWindow:secondWindow];
    if (self) {
         // other stuff
    }
    return self;
}

注意:您的新窗口原点/大小的变量名称是错误的;请检查它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-26
    • 2012-09-07
    • 1970-01-01
    相关资源
    最近更新 更多