从NSDocument类访问主窗口

时间:2012-01-08 15:38:03

标签: macos cocoa nswindow nsdocument

我有一个NSDocument类,我需要访问主菜单窗口,这是一个在应用程序启动时打开的窗口。当我从应用程序在该窗口中操作时似乎都工作,但是当我尝试从readFromFileWrapper:ofType:error:窗口执行相同的操作时,我访问的窗口似乎是零。为什么会这样?

编辑:一些处理此问题的代码:

- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper ofType:(NSString *)typeName error:(NSError **)outError
{
    if([[NSFileManager alloc] fileExistsAtPath:[NSString stringWithFormat:@"%@/Project.plist",[[self fileURL] path]]]) {
        NSLog(@"%@", [[self fileURL] path]);

        NSDictionary *project = [NSDictionary dictionaryWithContentsOfFile:[NSString stringWithFormat:@"%@/Project.plist",[[self fileURL] path]]];

        if([[project objectForKey:@"type"] isEqualToString:@"vote"]) {

            [self openProject:[[self fileURL] path] type:@"vote"];

            return YES;

        } else if([[project objectForKey:@"type"] isEqualToString:@"quiz"]) {

            [self openProject:[[self fileURL] path] type:@"quiz"];

            return YES; 

        } else {
            return NO;
        }
    } else {
        return NO;
    }
}

这是我的readFromFileWrapper:ofType:error:方法。这是我的openProject:type:方法:

-(void)openProject:(NSString *)filepath type:(NSString *)type 
{
    NSLog(@"Opening project @ %@",filepath);
    NSLog(@"%@", [MainWindow description]);
    [projectDesignerView setFrame:[[[[MainWindow contentView] subviews] objectAtIndex:0] frame]];
    [projectDesignerToolbar setFrame:[MainWindow frame] display:FALSE];
    [[MainWindow contentView] replaceSubview:[[[MainWindow contentView] subviews]objectAtIndex:0] with:projectDesignerView];
    [[projectDesignerToolbar toolbar] setShowsBaselineSeparator:YES];
    [MainWindow setToolbar:[projectDesignerToolbar toolbar]];
    [MainWindow setRepresentedFilename:filepath];
    [MainWindow setTitle:[NSString stringWithFormat:@"%@ - %@", [[filepath lastPathComponent] stringByDeletingPathExtension], [projectDesignerToolbar title]]];
    NSString *path = [[NSBundle mainBundle] pathForResource:@"projectDesigner" ofType:@"html"];
    NSURL *url = [NSURL fileURLWithPath:path];
    [[projectDesignerWebview mainFrame] loadRequest:[NSURLRequest requestWithURL:url]];
}
NSLog(@"%@", [MainWindow description]);应该是主应用程序窗口时,

MainWindow返回nil。我认为问题是双击文件会重新分配所有内容,因此失败了。

2 个答案:

答案 0 :(得分:6)

你所要求的并不完全清楚。您提到MainWindowMainMenu.xib中的出口,但您没有指定定义出口的类。

如果此窗口设计为具有单个主“项目”窗口,则应在应用程序委托中指定outlet属性。

然后,您可以使用[(YourAppDelegate*)[NSApp delegate] mainWindow];等内容从其他类访问此内容。

但是,如果您试图获取对当前文档窗口的引用,那么它会更复杂一些。

默认情况下NSDocument没有window出口的原因是它设计用于处理与文档相关的各种窗口的NSWindowController实例。这样一个文档可以有多个窗口显示相同数据的不同视图,与文档相关的附加调色板等等。 NSWindowController的每个实例都有自己的窗口nib文件和window outlet。

默认情况下,如果您没有专门为文档创建和分配NSDocument实例,NSWindowController会为您创建一个NSWindowController实例。这是自动的,您甚至不需要知道窗口控制器存在。

这意味着如果您不自行管理包含NSWindowController个实例的文档窗口,则可以将窗口附加到由NSWindowController自动创建的NSDocument,如此:

/* Only implement this in an NSDocument instance where the 
   automatic window controller is being used.
   If the document has multiple window controllers, you must
   keep track of the main window controller yourself
   and return its window
*/
- (NSWindow*)documentWindow
{
    if([[self windowControllers] count] == 1)
    {
        return [[[self windowControllers] firstObject] window]; 
    }
    return nil;
}

答案 1 :(得分:2)

处理此问题的常用方法是将IBOutlet添加到NSDocument子类,然后将其挂接到.xib文件中的文档窗口。

在你的.h:

@interface MyDocument : NSDocument

@property (nonatomic, assign) IBOutlet NSWindow *docWindow;

@end

在你的.m:

@implementation MyDocument : NSDocument

@synthesize docWindow;

@end

然后,最重要的部分,打开MyDocument.xib(或其他任何名称),并将文件所有者的连接(假设它是您的NSDocument子类,默认情况下)拖到主文档窗口,并挂钩它取决于docWindow出口。

相关问题