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

Jer*_*y L 18 macos cocoa objective-c nsview nswindow

由于Xcode中OS X应用程序的模板似乎与空的app模板类似,因此以下内容用于添加视图和按钮(现在尝试不使用"界面"构建器):

- (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]);   
}
Run Code Online (Sandbox Code Playgroud)

iOS上的类似代码应该生成一个黄色框和一个按钮,但上面的代码只生成一个按钮,但视图不会显示.上面的代码有什么问题,以及如何让它以黄色背景显示视图?

Par*_*fna 18

使用setWantsLayer:NSView类的方法.

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]);  
Run Code Online (Sandbox Code Playgroud)

  • 这个答案很糟糕.您[明确告知](http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html#//apple_ref/doc/uid/20000014-SW61 )不要在图层支持的视图中触摸支持层(在这种情况下使用`-setWantsLayer:`而不调用`-setLayer:`的视图).来自文档:**使用图层支持的视图时,不应直接与图层进行交互** (5认同)
  • @JeremyL:不,因为图层托管视图(如果你设置图层就是你得到的)不能有任何子视图.如果你想让你的按钮位于背景之上,它需要是一个子视图(不是分层的重叠视图可能无法正常工作,如果一个是图层托管,几乎肯定不会).由于您的按钮需要是子视图,因此黄色背景不能是图层托管视图. (4认同)

Lil*_*ard 5

NSView默认情况下,Cocoa中的s不是图层支持的.我怀疑如果你输入

NSLog(@"%@", view.layer);
Run Code Online (Sandbox Code Playgroud)

你会看到它nil.

在iOS中,所有视图都有图层.但在OS X上,视图没有图层.此外,在OS X上有2个"模式"的层支持视图.这就是所谓的"层支持视图"和"层托管视图".图层支持的视图使用CoreAnimation图层来缓存绘制的数据,但不允许您以任何方式与图层交互.图层托管视图使用CALayer您明确提供的视图,您可能会想要使用该图层.但是,使用图层托管视图,您可能无法添加任何子视图,或使用内置NSView绘图机制.图层托管视图只能用作CoreAnimation图层层次结构的根.

鉴于这一切,您应该完全避免使用CoreAnimation进行查看.

一个人可能NSBox会做你想做的事.您当然可以在那里设置填充颜色,关闭边框,并将样式设置为自定义.我只是不是100%肯定它将绘制为一个简单的填充矩形颜色.或者,您可以定义自己的NSView绘制颜色的子类-drawRect:.


Mar*_*ter 5

为了扩展Kevin Ballard的建议,执行此操作的经典方法是子类化NSView并覆盖该-drawRect:方法.NSRectFill是一个非常方便的函数,用于填充矩形而无需创建贝塞尔曲线路径:

- (void)drawRect:(NSRect)rect
{
    [[NSColor yellowColor] set];
    NSRectFill(rect);
}
Run Code Online (Sandbox Code Playgroud)