如何确保文档窗口记住其位置

时间:2013-10-18 04:25:22

标签: nspersistentdocument

我正在使用标准的AppKit NSPersistentDocument文档库应用程序,并且希望文档的窗口能够记住它的位置并在上次关闭的相同位置打开。

请注意,在窗口中设置IB中的autosavename将导致所有文档在相同位置打开。我希望文档根据文档文件名记住它的位置。

我已经将NSPersistentDocument子类化,并且当前在windowControllerDidLoadNib:函数中设置了自动保存名称。这几乎可以正常工作,除非我在没有关闭应用程序的情况下重复打开和关闭同一个文档,然后每次窗口的高度增加少量(26像素),几乎就像它在执行级联操作一样。但是,如果我完全关闭应用程序并重新打开它,那么文档会完全记住它以前的位置。我做错了什么或这是一个错误。是否有一些我应该做的清理工作,以确保每次重新打开窗口时都不会调整窗口大小。

// NSPersistentDocument subclass

- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
    LOG(@"windowControllerDidLoadNib called...");
    [super windowControllerDidLoadNib:aController];

    if ([self autoSaveName] != nil) {
        [aController setWindowFrameAutosaveName:[self autoSaveName]];
    }

    [aController setShouldCascadeWindows:NO];

}
- (NSString*)autoSaveName
{
    return [[self fileURL] lastPathComponent];
}

如果我添加以下代码以向其高度添加22个像素

- (NSRect)windowPositionPreference {
    LOG(@"printUserDefaults called");

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *autosaveNameKey = [NSString stringWithFormat:@"NSWindow Frame %@", [self autoSaveName]];
    NSString *frameString = [defaults objectForKey:autosaveNameKey];
    NSArray *array = [frameString componentsSeparatedByString:@" "];
    CGFloat x = [[array objectAtIndex:0] floatValue];
    CGFloat y = [[array objectAtIndex:1] floatValue];
    CGFloat width = [[array objectAtIndex:2] floatValue];
    CGFloat height = [[array objectAtIndex:3] floatValue];

    NSRect rect = CGRectMake(x, y, width, height+22);
    FLOG(@" window frame = %fx, %fy, %fw, %fh", x, y, width, height);

    return rect;
}

然后在- (void)windowControllerDidLoadNib:(NSWindowController *)aController

中设置框架
NSRect rect = [self windowPositionPreference];
    [aController.window setFrame:rect display:YES];

该职位似乎完全保留。当然,autosavename只是为了工作。

1 个答案:

答案 0 :(得分:1)

以上情况仍然没有奏效,但经过一番捣乱后,我放弃使用autosavename因为自动级联似乎无法禁用。

现在我只保留自己的首选项并使用下面的代码设置窗口框架。到目前为止它似乎工作得很好,我没有必要创建自己的NSWindowController或NSWindow的子类。

// Methods in subclassed NSPersistentDocument

- (void)windowControllerDidLoadNib:(NSWindowController *)aController {
    [aController setShouldCascadeWindows:NO];

    _mainWindow = aController.window;
    [self restoreSavedWindowPosition];

}

- (void)close {

    [self saveWindowPosition];
    [super close];

}

- (void)saveWindowPosition {

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSString *autosaveNameKey = [NSString stringWithFormat:@"OSWindow Frame %@", [self autoSaveName]];

    [defaults setObject:[self stringFromFrame] forKey:autosaveNameKey];
}

- (void)restoreSavedWindowPosition {

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSString *autosaveNameKey = [NSString stringWithFormat:@"OSWindow Frame %@", [self autoSaveName]];

    NSString *frameString = [defaults objectForKey:autosaveNameKey];

    // Do nothing if it has not been set
    if (frameString) {
        [_mainWindow setFrame:[self rectFromString:frameString] display:YES animate:YES];
    }
    else {
        // Set the default for new docs
        NSRect rect = CGRectMake(70, 350, 1000, 760);
        [_mainWindow setFrame:rect display:YES animate:YES];
    }

    return;
}

// Use the filename as the preferences key
- (NSString*)autoSaveName {

    return [[self fileURL] lastPathComponent];

}

- (NSString *)stringFromFrame {
    NSRect rect = _mainWindow.frame;
    rect.origin.y = rect.origin.y + 26;
    rect.size.height = rect.size.height - 26;

    return [self stringFromRect:rect];
}

- (NSString *)stringFromRect:(NSRect)rect {
    return [NSString stringWithFormat:@"%f %f %f %f", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height];
}

- (NSRect)rectFromString:(NSString*)string {
    NSRect rect;
    NSArray *array = [string componentsSeparatedByString:@" "];
    rect.origin.x = [[array objectAtIndex:0] floatValue];
    rect.origin.y = [[array objectAtIndex:1] floatValue];
    rect.size.width = [[array objectAtIndex:2] floatValue];
    rect.size.height = [[array objectAtIndex:3] floatValue];
    return rect;
}