web-dev-qa-db-ja.com

CocoaアプリでNSWindowにNSViewを追加する方法

XcodeのOS Xアプリのテンプレートは空のアプリテンプレートに似ているため、以下はビューとボタンを追加するために使用されます(今のところInterface Builderを使用しないようにします)。

- (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の同様のコードは黄色のボックスとボタンを生成するはずですが、上のコードはボタンのみを生成しますが、ビューは表示されません。上記のコードに何か問題がありますか?それを黄色の背景でビューに表示するにはどうすればよいですか?

19
Jeremy L

使用する 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]);  
18
Parag Bafna

Kevin Ballardの提案を拡張するには、これを行う古典的な方法は、NSViewをサブクラス化し、-drawRect:メソッドをオーバーライドすることです。 NSRectFillは、ベジェパスを作成せずに四角形を塗りつぶすための非常に便利な関数です。

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

CocoaのNSViewsは、デフォルトでは、レイヤーバッキングではありません。入力すると

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

nilであることがわかります。

IOSでは、すべてのビューにレイヤーがあります。ただし、OS Xでは、ビューにレイヤーはありません。さらに、OS Xにはレイヤー付きビューの2つの「モード」があります。「レイヤー付きビュー」と「レイヤーホスティングビュー」と呼ばれるものがあります。レイヤー付きビューはCoreAnimationレイヤーを使用して描画データをキャッシュしますが、レイヤーとのやり取りは一切許可されていません。レイヤーをホストするビューは、明示的に提供するCALayerを使用します。そのレイヤーを好きなように操作できます。ただし、レイヤーホスティングビューでは、サブビューを追加したりできなかったり、組み込みのNSView描画メカニズムを使用したりできません。レイヤーをホストするビューは、CoreAnimationレイヤー階層のルートとしてのみ使用する必要があります。

これらすべてを考慮して、ビューにCoreAnimationを使用することはおそらく避けてください。

NSBox が希望どおりの動作をする可能性があります。そこに塗りつぶしの色を設定し、境界線をオフにし、スタイルをカスタムに設定できます。単純に塗りつぶされた色の長方形として描画されるかどうかは、100%確実ではありません。あるいは、-drawRect:で色を描画する独自のNSViewサブクラスを定義できます。

5
Lily Ballard