objective-c macos cocoa nsview nswindow

objective c - ¿Cómo agregar un NSView a NSWindow en una aplicación Cocoa?



objective-c macos (3)

Para ampliar la sugerencia de Kevin Ballard, la forma clásica de hacer esto es NSView subclase NSView y anular el método -drawRect: . NSRectFill es una función muy conveniente para rellenar un rectángulo sin tener que crear una ruta más atractiva:

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

Dado que la plantilla de una aplicación OS X en Xcode parece ser similar a una plantilla de aplicación vacía, lo siguiente se usa para agregar una vista y un botón (tratando de no usar Interface builder por ahora):

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

Un código similar en iOS debería haber generado un cuadro amarillo y un botón, pero el código anterior solo produce un botón, pero la vista no se muestra. ¿Hay algún problema con el código anterior y cómo hacerlo para mostrar la vista con un fondo amarillo?


Use setWantsLayer: método 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]);


NSView s en Cocoa son, por defecto, no respaldados por capas. Sospecho que si escribes

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

Verás 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 capas en OS X. Hay lo que se denomina "vistas respaldadas por capas" y una "vista de alojamiento de capas". Una vista con respaldo de capa utiliza una capa CoreAnimation para almacenar en caché los datos dibujados, pero no se le permite interactuar con la capa de ninguna manera. Una vista de alojamiento de capas utiliza un CALayer que proporcionas explícitamente, y puedes CALayer con esa capa todo lo que quieras. Sin embargo, con una vista de alojamiento de capas no puede agregar subvistas ni utilizar el mecanismo de dibujo NSView . Una vista de alojamiento de capas solo debe usarse como la raíz de una jerarquía de capas CoreAnimation.

Dado todo esto, probablemente debas evitar usar CoreAnimation para tu vista.

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