2012-09-11 33 views
16

Desde la plantilla de una aplicación de OS X en Xcode parece ser similar a una plantilla de aplicación de vacío, se usa para añadir una vista y un botón (tratando de no utilizar el constructor de interfaz por ahora) lo siguiente:¿Cómo agregar un NSView a NSWindow en una aplicación Cocoa?

- (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]); 
} 

Código similar en iOS debería haber producido un cuadro amarillo y un botón, pero el código anterior solo produce un botón, pero la vista no se mostrará. ¿Hay algún problema con el código anterior y cómo hacer que muestre la vista con un fondo amarillo?

Respuesta

16

Utilice el método setWantsLayer: de la clase 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]); 
+0

NSView no tiene una propiedad backgroundColor, parece. ¡Casi echo de menos 'UIKit' ...! –

+5

Esta respuesta es mala. Usted está [explícitamente informado] (http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/Reference/NSView.html # // apple_ref/doc/uid/20000014-SW61) para no tocar la capa de respaldo en una vista de capa ver donde usaste '-setWantsLayer:' sin llamar '-setLayer:' primero). De los documentos: ** Al usar vistas respaldadas por capas, nunca deberías interactuar directamente con la capa ** –

+0

quieres decir, primero debes instanciar un CALayer, configurarlo en view.layer, y luego establecer wantsLayer en YES, y establecer el color de fondo ? –

5

NSView s en Cocoa no están, por defecto, respaldados por capa. Sospecho que si escribe

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

verá que es nil.

En iOS, todas las vistas tienen capas. Pero en OS X, las vistas no tienen capas. Además, hay 2 "modos" de vistas respaldadas por capa en OS X. Hay lo que se conoce como "vistas respaldadas por capa" y una "vista de alojamiento de capa". Una vista respaldada por capas utiliza una capa CoreAnimation para almacenar en caché los datos dibujados, pero no tiene permitido interactuar con la capa de ninguna manera. Una vista de alojamiento de capa utiliza un CALayer que usted proporciona explícitamente, y puede meter con esa capa todo lo que desee. Sin embargo, con una vista de alojamiento de capas, no puede agregar subvistas, o utilizar el mecanismo de dibujo incorporado NSView. Una vista de alojamiento de capa solo debe utilizarse como la raíz de una jerarquía de capa de CoreAnimation.

Dado todo esto, probablemente deberías evitar utilizar CoreAnimation para tu visualización.

Es posible que un NSBox haga lo que desee. Sin duda, puede establecer un color de relleno allí, desactivar el borde y establecer el estilo en personalizado. Simplemente no estoy 100% seguro de que dibujará como un simple rectángulo de color lleno. Alternativamente, puede definir su propia subclase NSView que dibuje un color en -drawRect:.

+0

sabes cómo hacer que la vista de presentación con un fondo de color amarillo? –

+0

@JeremyL: Estoy investigando eso ahora mismo. Principalmente hago iOS, así que espera. –

+0

@JeremyL, siempre hago lo que Kevin mencionó, use un NSBox en lugar de una vista personalizada. Simplemente establezca su tipo en personalizado, y luego puede (en IB o código) establecer su color de fondo, un color de borde (o sin borde si lo desea), y esquinas redondeadas si lo desea. – rdelmar

5

Para ampliar la sugerencia por Kevin Ballard, la manera clásica de hacerlo es a subclase NSView y reemplazar el método -drawRect:. NSRectFill es una función muy conveniente para el llenado de un rectángulo sin tener que crear un trazado Bézier:

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