如何在Cocoa应用程序中将NSView添加到NSWindow?

19

因为 Xcode 中 OS X 应用程序的模板似乎类似于空应用程序模板,所以以下代码用于添加一个视图和一个按钮(目前尝试不使用界面构建器):

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{       
    NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(100, 100, 100, 100)];

    view.layer.backgroundColor = [[NSColor yellowColor] CGColor];

    [self.window.contentView addSubview:view];

    NSRect frame = NSMakeRect(10, 40, 90, 40);
    NSButton* pushButton = [[NSButton alloc] initWithFrame: frame]; 
    pushButton.bezelStyle = NSRoundedBezelStyle;

    [self.window.contentView addSubview:pushButton];

    NSLog(@"subviews are %@", [self.window.contentView subviews]);   
}

在iOS上类似的代码应该会产生一个黄色的框和一个按钮,但是上面的代码只产生了一个按钮,而且视图没有显示出来。这段代码有问题吗?怎样才能使它显示一个黄色背景的视图呢?

3个回答

21

使用 NSView 类的 setWantsLayer: 方法。

NSView *view = [[NSView alloc] initWithFrame:NSMakeRect(100, 100, 100, 100)];
[view setWantsLayer:YES];
view.layer.backgroundColor = [[NSColor yellowColor] CGColor];

[self.window.contentView addSubview:view];

NSRect frame = NSMakeRect(10, 40, 90, 40);
NSButton* pushButton = [[NSButton alloc] initWithFrame: frame]; 
pushButton.bezelStyle = NSRoundedBezelStyle;

[self.window.contentView addSubview:pushButton];

NSLog(@"subviews are %@", [self.window.contentView subviews]);  

NSView似乎没有backgroundColor属性。我有点想念UIKit...! - Jeremy L
7
这个答案不好。你明确被告知,在使用带层的视图(即在没有先调用“-setLayer:”而使用“-setWantsLayer:”方法的视图)时,不要触及背景层。根据文档:在使用带层视图时,你应该从不直接与层进行交互 - Lily Ballard
你的意思是,首先实例化一个CALayer,将其设置为view.layer,然后将wantsLayer设置为YES,并设置背景颜色? - Jeremy L
4
@JeremyL: 不行,因为一个包含层的视图(如果你设置了层,这就是你得到的内容)不能有任何子视图。如果你想让你的按钮在背景上方,它需要成为一个子视图(重叠的视图如果不是分层的可能无法正常工作,如果其中一个是包含层的视图几乎肯定不会工作)。由于你的按钮需要成为一个子视图,黄色背景不能是一个包含层的视图。 - Lily Ballard
你如何将自定义类与该视图链接起来?@NSAddict - Hope

6

进一步阐述Kevin Ballard的建议,经典的方法是继承NSView并重写-drawRect:方法。使用NSRectFill函数可以非常方便地填充矩形,而无需创建贝塞尔路径:

- (void)drawRect:(NSRect)rect
{
    [[NSColor yellowColor] set];
    NSRectFill(rect);
}

5

NSView在Cocoa中默认情况下不支持图层(layer-backed)。我猜测如果你键入以下代码:

NSLog(@"%@", view.layer);

您会看到它是 nil

iOS中,所有视图都有层。但在OS X上,视图没有层。此外,在OS X上有两种“模式”的层支持视图。其中一种称为“层支持视图”,另一种称为“层主机视图”。层支持视图使用CoreAnimation层来缓存绘制数据,但您不能以任何方式与该层交互。层主机视图使用您明确提供的CALayer,您可以随意处理该层。但是,对于层主机视图,您不得添加任何子视图或使用内置的NSView绘图机制。层主机视图必须仅用作CoreAnimation层级结构的根。

考虑到所有这些,您应该尽可能避免在视图中使用CoreAnimation。

可能一个NSBox可以做到您想要的。您肯定可以在那里设置填充颜色,关闭边框并将样式设置为自定义。我只是不确定它是否会绘制为简单的填充颜色矩形。或者,您可以定义自己的NSView子类,在-drawRect:中绘制颜色。


你知道如何使视图显示为黄色背景吗? - Jeremy L
@JeremyL:我正在研究这个问题。我主要做iOS开发,所以请稍等。 - Lily Ballard
@JeremyL,我一直都像Kevin提到的那样,使用NSBox而不是自定义视图。只需将其类型设置为custom,然后您可以(在IB或代码中)设置其背景颜色、边框颜色(如果选择,则无边框)以及圆角。 - rdelmar
我尝试使用NSBox,但它带有一个“标题”,并且没有backgroundColor属性。 - Jeremy L
1
@JeremyL:你可以将标题设置为nil,将框类型设置为自定义,将边框类型设置为无。然后,背景颜色由fillColor控制。我建议你创建一个xib,在画布上拖动一个NSBox,并在那里玩弄属性。 - Lily Ballard
@JeremyL,你尝试使用一个框,但没有将它的类型设置为自定义——自定义框没有标题,但有填充颜色、边框颜色和边框类型。 - rdelmar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接