1

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

请注意,在窗口的 IB 中设置自动保存名称将导致所有文档在同一位置打开。我希望文档根据文档文件名记住其位置。

我已经将 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 只是为了工作。

4

1 回答 1

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;
}
于 2013-10-21T23:18:14.053 回答