0

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

总而言之,我用来执行此操作的方法是(相关代码在底部):

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

问题是窗口的实际内容视图中视图的自动调整大小掩码完全搞砸了。这是我在界面生成器中设置内容的方式:

布局

以下是表格视图滚动视图的自动调整大小掩码的设置方式:

表视图自动调整大小

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

标签自动调整大小

以下是应用内的结果:

实际结果

相关代码(来源于前述文章)

#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。包括一个示例项目,以防您想尝试重现该问题。

4

1 回答 1

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");
}
于 2011-08-25T15:13:01.583 回答