自定义NSWindow内容边距会导致自动调整掩码陷入困境

时间:2011-03-07 02:31:47

标签: objective-c cocoa nsview nswindow popover

我目前正在使用this Cocoa with Love文章中显示的方法来创建自定义的NSWindow子类。在示例中,我需要在窗口内容周围有大约10px的边距才能绘制箭头(我正在创建一个弹出式窗口)。我必须在整个窗口周围留下边距,而不仅仅是带有箭头的边缘,因为我希望能够更改箭头位置,而无需重新定位内容。

总而言之,我用来做这个的方法是(相关代码在底部):

  • 覆盖NSWindow的contentRectForFrameRect:frameRectForContentRect:styleMask:方法,在内容周围添加填充:
  • 将窗口的自定义绘制框架视图设置为contentView,然后覆盖contentView的setter和getter,以便将传入的视图添加为子视图< / strong>的框架视图。

问题是窗口的实际内容视图中内部的自动调整遮罩完全搞砸了。以下是我在界面构建器中设置内容的方法:

Layout

以下是如何设置表视图滚动视图的自动调整掩码:

Table View Autoresizing

以下是文本标签的自动调整掩码的设置方法:

Label Autoresizing

以下是应用程序中的结果:

Actual result

相关代码(源自上述文章)

#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]) { return; }
    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];
}

我认为也许popover内容在某种程度上越过边缘,所以我在内容视图周围画了一个边框,但不是,一切都是应该的。唯一的问题是内容视图中标签和表视图的自动调整掩码无法正常工作。非常感谢任何建议。

编辑:如果有人有兴趣,我已经在github上为这个弹出窗口/控制器开源了INPopoverController。如果您想尝试重现问题,请提供示例项目。

1 个答案:

答案 0 :(得分:1)

-( 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");
}