开发者

Resizing NSWindow to fit new NSViews results in views being drawn incorrectly

I have a NSWindowController with a setCurrentView method in which I use the following code to resize the window to the new view's size.

[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];

Edit: Added the resizeWindowForContentSize I found on 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]];
}

The problem I'm having is that as you switch between views (using NSToolbar) the views begin to move around in the contentView. Over time they actually draw further and further away until eventually there is just a blank view.


Instead of using the class methods:

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

use the instance methods:

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

instead. The instance methods take toolbars into account, and should be used whenever you have an NSWindow instance — which you do via [self window].

For example, assuming that’s the problem with your -resizeWindowForContentSize: method:

- (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]];
}


My guess is that you might be forgetting to take into account the toolbar height, and/or the 22 pixel height of the window's titlebar.

I've been using this category on NSWindow for longer than I can remember:

@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

You might be able to extract out of there what you need.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜