使用单独的.nibs并从App Delegate中获取逻辑

时间:2015-04-07 17:34:53

标签: objective-c xcode cocoa

我有一个使用标准模板的基于文档的应用程序。我在Main Menu.xib中有两个辅助面板,我的主要逻辑当前在App Delegate中,主要是通过我的一个面板上的按钮触发的App Delegate中的IBAction。一切都很好,但我知道它应该更好地组织。

我已经在第12章中按照Hillegass的建议实现了一个“首选项”面板。所以:

  • 创建一个名为AppController的自定义控制器,其中包含实例 PreferenceController。这在Main Menu.xib

  • 中实例化
  • 自定义PreferenceController类,它是的子类 NSWindowController。这会加载Preferences.xib

  • 在Preferences.xib中创建的首选项面板

在我开发应用程序之前,我想确定我正在以正确的方式组织事情。

我想将我的主要逻辑从App Delegate移出,可能移到App Controller中。我希望App Controller负责显示和隐藏各种面板,我希望每个面板都有自己的.xib。

我创建了另外两个NSWindowController的子类,并将它们作为AppController的ivars,以及PreferencesController,例如。 Panel1Controller& Panel2Controller。

我的问题是界面构建器不允许我将AppController中的IBAction连接到我的某个面板上的按钮。它只允许我连接到.xib文件的所有者,即Panel1.xib的Panel1Controller。

如果我将逻辑放在Panel1Controller中,我如何进入其中一个面板(比如Panel2Controller?)以隐藏它?

我是以正确的方式来做这件事的吗?

变得非常困惑......

非常感谢任何帮助!

此致

约翰

4 个答案:

答案 0 :(得分:0)

为了简单起见,我将所有由NSWindowController子类控制的nib元素移出主nib,并移动到与控制它们的(NSWindowController)子类同名的nib中。不要在子类标题中公开IBOutlets或IBActions(它们应该在该子类的源文件中的类扩展(" @interface MyWindowController()")中)。 另外,AppController是第二个应用代理吗?可能不是你想要的(只能有一个);如果是这样的话,你应该把它的逻辑合并到现有的app委托中。

答案 1 :(得分:0)

我刚遇到this方法。

这似乎完全取消了 NSWindowController ,并使AppController成为两个.xibs的文件所有者。这样,IB允许您在AppController中为每个窗口创建出口,并包含操作。

我使用这种方法创建了一个非常简单的双窗口应用程序,当按下另一个按钮时隐藏一个窗口。在我离开并重新组织我的主应用程序之前,我想确保我以正确的标准方式执行此操作(如果有的话)?

This页面与此方法相矛盾,通过说一个窗口=一个.xib +一个NSWindowController子类。

如果你采用后一种方式,当你无法在AppController中创建出口/动作时,一个窗口如何与另一个窗口交谈?在窗口的NSWindowController类中实现的动作无法看到另一个窗口的出口,那么它们如何通信呢?

这看起来很标准,基本的东西,但我找不到任何说明哪种方式是正确/最佳实践的来源。

答案 2 :(得分:0)

我读过有关here使用通知的另一种方法。

我仍然在想 - 这是最常见的"接受"在单独的.nibs中加载两个或多个窗口并让它们相互通信的方法?我很惊讶这个信息很难找到。

答案 3 :(得分:0)

如果您要遵循此模式,将AppDelegate和AppController分开,那么您的MainMenu.xib不应包含任何类型的窗口对象......它应该只包含应用程序菜单。每个额外的窗口(NSWindow / NSPanel等)都有自己的.xib和它自己的NSWindowController。

有两种方法可以为您的属性(IBOutlets)和方法(IBActions)分配引用:1)以编程方式,2)通过Interface Builder。让我们来介绍第二种方法!

为了能够从Interface Builder(IB)连接起来,您需要引用IB内的目标对象。对于MainMenu.xib文件,它会自动进行设置:MainMenu.xib包含一个" AppDelegate"对象参考。 Object引用公开了AppDelegate类中以" IBAction"为前缀的属性和方法。和" IBOutlet"宏。我写 Object (大写 O ),因为它是"对象库"中可用的小部件。在IB。

您可以通过拖动"对象"轻松地在.xib文件中创建自定义对象的实例(通过IB)。从对象库到您的.xib的小部件。然后将Object的类设置为自定义类的类。完成此操作后,您的自定义类对象中的IBActions和IBOutlet将在IB中可用。 [注意:执行此操作时要记住的一件事是,当您加载xib时,对象将自动实例化。无需从AppDelegate中分配和初始化...你仍然需要调用showWindow:on it。

正如您所提到的,另一种方法是简单地拥有AppController拥有的所有其他.xib文件。这样会很方便,但它也可以100%远离您首先尝试遵循的架构。换句话说,如果您要遵循这种风格,为什么不首先跳过单独的AppDelegate和AppController,只需坚持使用前者(这将是一个Controller和Delegate)。