开发者

Custom NSWindow content margin causes mess up with autoresizing mask

I'm currently using the method shown in this Cocoa with Love article to create a custom NSWindow subclass. As in the example, I needed to have a roughly 10px margin around the content of the window in order to draw an arrow (I'm creating a popover style window). I had to have the margin around the entire window instead of just the side with the arrow on it because I wanted to be able to change the arrow position without having to reposition the content.

To summarize, the method I'm using to do this is (relevant code is at the bottom):

  • Override the contentRectForFrameRect: and frameRectForContentRect:styleMask: methods of NSWindow to add the padding around the content:
  • Sets the custom drawn frame view of the window as the contentView and then overrides the setter and getter for the contentView so that the view that is passed in is added as a subview of the frame view.

The problem is that the autoresizing masks of views inside the actual content view of the window are completely messed up. Here is how I'm setting up the content in interface builder:

Custom NSWindow content margin causes mess up with autoresizing mask

Here's how the autoresizing mask of the table view scroll view is set up:

Custom NSWindow content margin causes mess up with autoresizing mask

And here's how the text label's autoresizing mask is set:

Custom NSWindow content margin causes mess up with autoresizing mask

And here's what the result looks like in-app:

Custom NSWindow content margin causes mess up with autoresizing mask

Relevant code (derived from the aforementioned article)

#define CONTENT_MARGIN 10.0

- (NSRect)contentRectForFrameRect:(NSRect)windowFrame
{
    windowFrame.origin = NSZeroPoint;
    return NSInsetRect(windowFrame, CONTENT_MARGIN, ICONTENT_MARGIN);
}

- (NSRect)frameRectForContentRect:(NSRect)contentRect
{
    return NSInsetRect(contentRect, -CONTENT_MARGINT, -CONTENT_MARGIN);
}

+ (NSRect)frameRectForContentRect:(NSRect)contentRect
                        styleMask:(NSUInteger)windowStyle
{
    return NSInsetRect(contentRect, -CONTENT_MARGIN, -CONTENT_MARGIN);
}


- (NSView*)contentView
{
    return _popoverContentView;
}

- (void)setContentView:(NSView *)aView
{
    if ([_popoverContentView isEqualTo:aView]) { re开发者_StackOverflow社区turn; }
    NSRect bounds = [self frame];
    bounds.origin = NSZeroPoint;
    SearchPopoverWindowFrame *frameView = [super contentView];
    if (!frameView) {
        frameView = [[[SearchPopoverWindowFrame alloc] initWithFrame:bounds] autorelease];
        [super setContentView:frameView];
    }
    if (_popoverContentView) {
        [_popoverContentView removeFromSuperview];
    }
    _popoverContentView = aView;
    [_popoverContentView setFrame:[self contentRectForFrameRect:bounds]];
    [_popoverContentView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
    [frameView addSubview:_popoverContentView];
}

I thought that maybe the popover content was going over the margins somehow, so I drew a border around the content view, but no, everything is as should be. The only issue is that the autoresizing masks of the label and table view inside the content view do not work as they should. Any advice is greatly appreciated.

EDIT: If anyone's interested, I've open-sourced the complete code for this popover window/controller on github as INPopoverController. Includes a sample project in case you want to try and reproduce the issue.


-( void )scaleWindowForHeight:( float )height
{
    if (height > 22)
    {
        NSWindow* window = [self window];
        NSRect old_window_frame = [window frame];
        NSRect old_content_rect = [window contentRectForFrameRect: old_window_frame];
        NSSize new_content_size = NSMakeSize( old_window_frame.size.width, height );
        // need to move window by Y-axis because NSWindow origin point is at lower side:
        NSRect new_content_rect = NSMakeRect( NSMinX( old_content_rect ), NSMaxY( old_content_rect ) - new_content_size.height, new_content_size.width, new_content_size.height );
        NSRect new_window_frame = [window frameRectForContentRect: new_content_rect];
        [window setFrame: new_window_frame  display:YES  animate: [window isVisible] ];
    }
    else
        NSLog(@"window size too small");
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜