识别正确的窗口框架大小以填充背景颜色

时间:2014-05-10 19:44:45

标签: objective-c macos cocoa

我正在使用Cocoa进行开发,目前我在填充NSWindowController的背景时遇到了问题。

我知道如果你想自定义你的cocoa应用程序,那么子类化是前进的方法。因此,我创建了一个名为whiteView的自定义NSView,并将此视图作为子视图添加到我的windowController contentView;但是,完全填充窗口背景存在一些问题。任何人都可以解释我如何让颜色覆盖窗口框架的整个表面区域。谢谢

这是我到目前为止的结果。

1)这是我保持原样的窗口,注意白色只覆盖了窗户的一半。 When I dont have the window maximised

2)当我向远端和底部调整窗口时,这是同一个窗口。白色屏幕似乎足够伸展,以便覆盖元素。 enter image description here

这是我创建自定义视图的方式

- (void)drawRect:(NSRect)dirtyRect
{
    [super drawRect:dirtyRect];
    [[NSColor whiteColor] set];
    NSRectFill([self bounds]);
}

这就是我如何将视图涂抹在窗户上。

WhiteView *whiteBackgroundView = [[WhiteView alloc] initWithFrame:self.window.frame];
[self.window.contentView addSubview:whiteBackgroundView positioned:NSWindowBelow relativeTo:self.window.contentView];

我需要做些什么才能正确地让我的窗口背景完全覆盖白色?

1 个答案:

答案 0 :(得分:2)

首先,简单的解决方案是使用-[NSWindow setBackgroundColor:]来设置窗口的背景颜色。不需要观点。

如果您仍然对如何修复基于视图的方法感兴趣,那么您可能没有设置视图的自动调整掩码以使其遵循视图中的更改,这可能是错误的。窗口大小。例如,您可以执行[whiteBackgroundView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]

但是,您也可以将whiteBackgroundView设置为窗口contentView,而不是将其设置为子视图。窗口的内容视图始终保持填充窗口内容rect所需的大小。窗口的所有其他视图都是白色背景视图的子视图。在我看来,这比把它当成恰好在后面的兄弟姐妹更好。使用兄弟视图之间的相对排序来实现特定的渲染顺序是一种破解。

最后,如果超类本身为super,则没有理由在-drawRect:中调用NSView的实施。 NSView在其-drawRect:中没有进行任何绘图。此外,您的子类对其边界的整个绘制内容承担全部责任,因此您无论如何都要过度绘制所绘制的super。 (另外,您只需填写dirtyRect而不是[self bounds]。)

虽然您已经完成了这项工作,但由于您的课程已填写其范围,因此您应覆盖-isOpaque以返回YES进行优化。


更新:关于视图的框架:如果它不是窗口的内容视图,那么您希望将其框架设置为其预期的超视图边界。因此,如果您希望self.window.contentView.bounds填充内容视图,则应该使用whiteBackgroundView

更一般地说,如果你想要一个窗口的内容rect,你可以[window contentRectForFrameRect:window.frame]。但是,如果视图将成为窗口的内容视图,则不需要将其框架设置为特定的任何内容。它会自动调整大小。


更新2:

将视图层次结构从原始内容视图转移到新的内容视图(当您将白色背景视图设为内容视图时):

NSArray* subviews = [self.window.contentView.subviews copy];
[subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
[whiteBackgroundView setSubviews:subviews];
[subviews release];

(写作手动保留释放。如果使用ARC,只需删除-release调用。)

关于要使用的帧,如第一次更新中所述:请记住,视图的帧应该在其superview的坐标系中表示。因此,正如我所说,如果您将新视图放入内容视图中,self.window.contentView.bounds将起作用。窗口的框架和内容矩形位于屏幕坐标中。它们对于定位视图完全不正确。