Как добавить NSView в NSWindow в приложении Cocoa?
Так как шаблон приложения OS X в Xcode, похоже, похож на пустой шаблон приложения, для добавления представления и кнопки используется (вместо этого не пытаться использовать построитель интерфейса):
- (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 должен был создать желтую рамку и кнопку, но вышеприведенный код создает только кнопку, но представление не будет отображаться. Что-то не так с приведенным выше кодом и как заставить его отображать представление с желтым фоном?
Ответы
Ответ 1
Использовать метод 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]);
Ответ 2
NSView
в Cocoa по умолчанию не поддерживаются на уровне слоев. Я подозреваю, что если вы наберете
NSLog(@"%@", view.layer);
вы увидите, что это nil
.
В iOS все представления имеют слои. Но в OS X в представлениях нет слоев. Кроме того, есть 2 "режима" вид с поддержкой слоев на OS X. Там, что называется "просмотры с поддержкой слоев" и "вид размещения на уровне слоев". Скрытый слой использует слой CoreAnimation для кэширования данных, но вам не разрешено взаимодействовать со слоем каким-либо образом. В представлении с уровнем размещения используется CALayer
, который вы явно предоставляете, и вы можете использовать этот слой, который вам нужен. Тем не менее, при представлении на уровне слоев вы не можете добавлять какие-либо подзаголовки или использовать встроенный механизм рисования NSView
. Слой-хостинг должен использоваться только как корень иерархии уровня CoreAnimation.
Учитывая все это, вам, вероятно, следует избегать использования CoreAnimation для вашего представления.
Возможно, что NSBox
будет делать то, что вы хотите. Вы можете, конечно, установить цвет заливки, отключить границу и установить стиль в обычном режиме. Я просто не на 100% уверен, что он будет рисовать как простой заполненный прямоугольник цвета. В качестве альтернативы вы можете определить свой собственный подкласс NSView
, который рисует цвет в -drawRect:
.
Ответ 3
Чтобы расширить предложение Кевина Балларда, классический способ сделать это - подклассом NSView
и переопределить метод -drawRect:
. NSRectFill
- очень удобная функция для заполнения прямоугольника без создания пути безье:
- (void)drawRect:(NSRect)rect
{
[[NSColor yellowColor] set];
NSRectFill(rect);
}