MacRuby + Interface Builder:如何显示,然后关闭,然后再次显示一个窗口

时间:2011-01-30 13:40:28

标签: xcode data-binding interface-builder macruby window-management

我是MacRuby和Cocoa的完整n00b,所以在回答时请记住这一点 - 我需要大量细节和解释。 :)

我已经设置了一个简单的项目,里面有2个窗口,这两个窗口都是用Interface Builder构建的。第一个窗口是使用表视图的简单帐户列表。它下面有一个“+”按钮。当我点击+按钮时,我想显示一个“添加新帐户”窗口。

我还有一个AccountsController < NSWindowController和一个AddNewAccountController < NSWindowController类,设置为这些窗口的代理,使用相应的按钮单击方法连接,以及引用以引用所需的窗口。

当我点击“帐户”窗口中的“+”按钮时,我会触发此代码:

    @add_account.center
    @add_account.display
    @add_account.makeKeyAndOrderFront(nil)
    @add_account.orderFrontRegardless

第一次单击+按钮时这很有用。一切都显示出来,我能够输入我的数据并将其绑定到我的模型。但是,当我关闭添加新帐户表单时,情况开始变坏。

如果我将添加新帐户窗口设置为在关闭时释放,那么第二次单击+按钮时,窗口仍会弹出,但它已冻结。我无法点击任何按钮,输入任何数据,甚至关闭表格。我认为这是因为表单的代码已经发布,所以没有消息循环处理表单......但我不完全确定这一点。

如果我将添加新帐户窗口设置为在关闭时不释放,则第二次单击+按钮,窗口显示正常并且可用 - 但它仍然具有我之前输入的所有数据。 ..它仍然绑定到我以前的Account类实例。

我做错了什么?当我点击“帐户”表单上的+按钮时,创建“添加新帐户”表单的新实例,创建新帐户模型,将该模型绑定到表单并显示表单的正确方法是什么?

......这一切都在OSX 10.6.6,64bit上进行,使用XCode 3.2.4

1 个答案:

答案 0 :(得分:1)

问题是它不会每次都创建窗口。关闭时释放是一个令人烦恼的选项,通常仅在窗口关闭时知道窗口控制器也被释放时使用。 (注意我从来没有使用过MacRuby所以我会在Obj-C中给出代码,因为我知道它是正确的,希望你可以转换它。我将假设GC应该与MacRuby一样开启。)< / p>

现在有两种方法可以做到这一点。我不完全确定你的NIB /类是如何设置的,因为它可能是两种方式之一。

-

解决问题的第一种方法是使用你用来引用表单元素的出口,当你再次显示窗口时将它们删空,例如[myTextField setStringValue:@“”]。如果你正在使用cocoa绑定,那么它有点棘手,但基本上你必须确保绑定的对象被消隐。如果你是Cocoa的新手,我建议不要使用绑定。

-

第二种方法是使AddNewAccountController类成为NSWindowController的子类。当您按下+按钮时,您将创建一个新实例并显示它(记得将​​其存储在ivar中)。最好的方法就是这样:

if (!addAccountController) {
    addAccountController = [[AddNewAccountController alloc] initWithWindowNibName:@"AddNewAccountController"];
    [[addAccountController window] setDelegate:self];
}
[addAccountController showWindow:self];

如果窗口已经可见,这可以防止生成新实例。然后,您需要实现委托:

- (void)windowWillClose:(NSNotification *)notification {
    //If you don't create the account in the AddNewAccountController then do it here
    addAccountController = nil;
}

显然,您需要将窗口移动到名为“AddNewAccountController”的单独NIB。在这个NIB中,确保将File的Owner的类设置为AddNewAccountController,然后将File的Owner的窗口连接到窗口。

设置完所有这些后,每次都会有一个新的控制器/窗口。它还具有将笔尖和控制器分成更集中的单元的好处。

-

最后一件事。虽然可以在窗口中执行此类操作,但您最终可能希望通过工作表执行此操作,因为这样可以防止添加帐户窗口隐藏在其他窗口后面的可能性。