向MainWindow添加视图或窗口

时间:2011-09-22 08:12:38

标签: objective-c macos cocoa

我绊倒了一些我无法掌握的基本概念。我希望,有人可以为我清理一些事情,因为我找不到资源,这可以解释这一点。或许,它是在明亮的开放,我只是没有看到它。

到目前为止理解:MainWindow持有菜单,因此或多或少是必不可少的。 info.plist保存nib,它在appstart上加载。

到目前为止还不了解:我正在尝试单个窗口应用程序。我可以在appDelegate中做任何事情(到目前为止工作正常)并且我可以有一个额外的控制器,我可以从MainWindow连接到UIElements(到目前为止虽然很好)。但是:我真正想做的是,有一个MainWIndow,它只有菜单,以及随后加载和添加的单独的控制器和笔尖(后面可能甚至超过一个)。

我的问题:

  • 使用NSWindowControllerNSViewController?为什么? (我会使用NSViewController

  • 实例化的内容,地点和方式(可能在appDelegate的didFinishLaunching中?)

  • 如何将窗口或视图添加到唯一的主窗口而不是第二个独立窗口(我还没有使用多个文档)

Thanx很多,任何想法都赞赏!

1 个答案:

答案 0 :(得分:22)

  

到目前为止还不了解:我正在尝试单个窗口应用程序。我可以在appDelegate中做任何事情(到目前为止工作正常)并且我可以有一个额外的控制器,我可以从MainWindow连接UIElements(到目前为止工作虽然很好)。但是:我真正想做的是,有一个MainWIndow,它只有菜单,以及随后加载和添加的单独的控制器和笔尖(后面可能甚至超过一个)。

为了清楚起见,MainWindow是一个nib文件,所以我将它称为MainWindow.nib。它是应用程序的Info.plist文件中指定的标准nib文件名,作为应用程序启动时要加载的nib文件。

默认情况下,Xcode会创建一个包含主菜单和主窗口的MainWindow.nib文件。您可以从MainWindow.nib文件中删除该窗口,并使用另一个nib文件来保存该窗口。让我们调用另一个nib文件MyWindow.nib。

  

使用NSWindowController或NSViewController?为什么? (我倾向于viewController)

由于您将拥有一个单独的nib文件来保存窗口,因此您将使用NSWindowController。创建NSWindowController的子类,例如MyWindowController,负责控制存储在MyWindow.nib中的窗口。此子类将具有指向该窗口中的用户界面元素的出口,以及可能在MyWindow.nib中定义的其他对象。

执行此操作时,务必在MyWindow.nib中执行以下操作:

  • 将文件所有者设置为MyWindowController类型;

  • 将文件所有者的window出口连接到窗口对象。

NSViewController用于管理通常从nib文件加载的视图,它不适用于Windows。

您可以重复此窗口 - .nib文件中的窗口,NSWindowController的子类来管理该窗口 - 根据需要为多个窗口。

  

实例化的内容,地点和方式(大概是在appDelegate的didFinishLaunching中?)

由于您需要在应用程序中使用单个窗口,因此应用程序委托的一个选项是将引用(实例变量,声明的属性)保存到管理该窗口的单个窗口控制器。然后,在-applicationDidFinishLaunching:中,实例化所述控制器。

例如:

// MyAppDelegate.h

@class MyWindowController;

@interface MyAppDelegate : NSObject <NSApplicationDelegate>
@property (retain) MyWindowController *myWindowController;
@end

// MyAppDelegate.m

#import "MyAppDelegate.h"
#import "MyWindowController.h"

@implementation MyAppDelegate

@synthesize myWindowController;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    self.myWindowController = [[[MyWindowController alloc]
        initWithWindowNibName:@"MyWindow"] autorelease];
    [self.myWindowController showWindow:self];
}

…
@end

如果你想要更多的窗口,只需要声明实例变量/属性来保存它们相应的控制器并像上面那样实例化控制器。

  

如何将窗口或视图添加到唯一的主窗口而不是第二个独立窗口(我还没有使用multiDocumentApps)

您确定要在主窗口中添加窗口吗?如果是这样,那就称为附加窗口。您可以使用上面的机制(将窗口放在其自己的nib文件中,使用NSWindowController的子类来管理它,让原始MyWindowController保持对附加的引用(实例变量,声明的属性)窗口控制器,并在适当时实例化它/加载附加的窗口nib文件),然后使用-[NSWindow - addChildWindow:ordered:]将辅助窗口附加到主窗口。

例如,考虑MyWindowController在MyWindowController.m中有一个声明的属性secondaryWindowController

- (void)someAction:(id)sender {
    // If the secondary window hasn't been loaded yet, load it and add its
    // window as a window attached to the main window
    if (self.secondaryWindowController == nil) {
        self.secondaryWindowController = [[[MySecondaryWindowController alloc]
            initWithWindowNibName:@"MySecondaryWindow"] autorelease];
        [[self window] addChildWindow:self.secondaryWindowController.window
                              ordered:NSWindowAbove];
    }
}

如果要将视图添加到主窗口,最简单的方法是直接在nib文件中执行此操作。

如果您需要/想要以编程方式执行此操作,则需要引用该视图,然后将其添加到主窗口的内容视图中,例如:

[self.window.contentView addSubView:someView];

您可以通过编程方式创建someView或从单独的nib文件加载它。在后一种情况下,过程与上面描述的过程非常相似,但不是使用NSWindowController的子类,而是使用NSViewController的子类。

例如,在MyWindowController.m中:

- (void)anotherAction:(id)sender {
    // If the view hasn't been loaded yet, load it and add it
    // as a subview of the main window's content view
    if (self.someViewController == nil) {
        self.someViewController = [[[MyViewController alloc]
            initWithNibName:@"MyView" bundle:nil] autorelease];
        // You'll probably want to set the view's frame, e.g.
        // [self.someViewController.view setFrame:...];
        [self.window.contentView addSubview:self.someViewController.view];
    }
}