Подтвердить что ты не робот

Изменение размера NSWindow для соответствия новым NSView приводит к неправильному отображению представлений

У меня есть NSWindowController с методом setCurrentView, в котором я использую следующий код, чтобы изменить размер окна на новый размер.

[self resizeWindowForContentSize: [newView frame].size];

NSView *contentView = [[self window] contentView];
NSDictionary *ani = [NSDictionary dictionaryWithObject:transition 
                                                forKey:@"subviews"];
[contentView setAnimations:ani];    
[[contentView animator] replaceSubview:currentView with:newView];

Изменить: добавлен resizeWindowForContentSize, который я нашел на CocoaDev.

- (void)resizeWindowForContentSize:(NSSize) size {
    NSRect windowFrame = [NSWindow contentRectForFrameRect:[[self window] frame]
        styleMask:[[self window] styleMask]];
    NSRect newWindowFrame = [NSWindow frameRectForContentRect: 
        NSMakeRect( NSMinX( windowFrame ), NSMaxY( windowFrame ) - size.height, size.width, size.height )
    styleMask:[[self window] styleMask]];
    [[self window] setFrame:newWindowFrame display:YES animate:[[self window] isVisible]];
}

Проблема, с которой я сталкиваюсь, заключается в том, что при переключении между представлениями (используя NSToolbar) представления начинают перемещаться в contentView. Со временем они на самом деле все больше и больше уходят, пока в конце концов не появится просто пустой вид.

4b9b3361

Ответ 1

Вместо использования методов класса:

+[NSWindow frameRectForContentRect:styleMask:]
+[NSWindow contentRectForFrameRect:styleMask:]

используйте методы экземпляра:

-[NSWindow frameRectForContentRect:]
-[NSWindow contentRectForFrameRect:]

вместо этого. Методы экземпляра учитывают панели инструментов и должны использоваться всякий раз, когда у вас есть экземпляр NSWindow, который вы выполняете с помощью [self window].

Например, если предположить, что проблема с вашим методом -resizeWindowForContentSize::

- (void)resizeWindowForContentSize:(NSSize) size {
    NSWindow *window = [self window];

    NSRect windowFrame = [window contentRectForFrameRect:[window frame]];
    NSRect newWindowFrame = [window frameRectForContentRect:
        NSMakeRect( NSMinX( windowFrame ), NSMaxY( windowFrame ) - size.height, size.width, size.height )];
    [window setFrame:newWindowFrame display:YES animate:[window isVisible]];
}

Ответ 2

Я предполагаю, что вы можете забыть учитывать высоту панели инструментов и/или высоту 22 пикселя окна заголовка окна.

Я использую эту категорию на NSWindow дольше, чем я помню:

@implementation NSWindow (MDAdditions)

- (CGFloat)toolbarHeight {
    NSToolbar *toolbar = [self toolbar];
    CGFloat toolbarHeight = 0.0;
    NSRect windowFrame;

    if (toolbar && [toolbar isVisible]) {
        windowFrame = [[self class] contentRectForFrameRect:[self frame]
                                                  styleMask:[self styleMask]];
        toolbarHeight = NSHeight(windowFrame) - 
                        NSHeight([[self contentView] frame]);
    }
    return toolbarHeight;
}

- (void)resizeToSize:(NSSize)newSize {
    CGFloat newHeight = newSize.height + [self toolbarHeight];
    CGFloat newWidth = newSize.width;

    NSRect aFrame = [[self class] contentRectForFrameRect:[self frame]
                                                styleMask:[self styleMask]];

    aFrame.origin.y += aFrame.size.height;
    aFrame.origin.y -= newHeight;
    aFrame.size.height = newHeight;
    aFrame.size.width = newWidth;

    aFrame = [[self class] frameRectForContentRect:aFrame
                                         styleMask:[self styleMask]];
    [self setFrame:aFrame display:YES animate:YES];
}

@end

Возможно, вы сможете извлечь из него то, что вам нужно.