2009-11-12 10 views
25

Estoy teniendo un momento difícil envolver mi cabeza alrededor de vistas de carga con Interface Builder y NSViewController.NSViewController y múltiples subvistas de una punta

Mi objetivo es tener una vista que coincida con la siguiente descripción: Barra superior en la parte superior (como una barra de herramientas pero no exactamente) que abarca todo el ancho de la vista y una segunda "vista de contenido" a continuación. Esta vista compuesta es propiedad de mi subclase NSViewController.

tenía sentido utilizar el Interface Builder para esto. Creé un plum de vista, y agregué dos subvistas, las distribuí correctamente (con la barra superior y la vista de contenido). Establecí File's Owner como MyViewController, y tomas de corriente conectadas y demás.

Las vistas que deseo cargar (la barra y el contenido) también están en sus propias puntas (esto podría ser lo que me está molestando) y esas plumillas tienen su Clase personalizada configurada en la subclase NSView respectiva donde corresponda. No estoy seguro de lo que establece como su File's Owner (supongo MyController como debe ser su propietario).

Por desgracia, cuando init una instancia de MyViewController ninguno de mis puntas realidad mostrar. Lo he agregado al ContentView de mi ventana correctamente (lo he comprobado de otra manera), y en realidad, cosas como la carga. Es decir, awakeFromNib se envía a la vista de barra, pero no se muestra en la ventana. Creo que definitivamente tengo algunos cables cruzados en algún lado. Tal vez alguien podría echar una mano para aliviar algo de mi frustración?

EDITAR algo de código para mostrar lo que estoy haciendo

El controlador se carga cuando mi solicitud finaliza el lanzamiento, desde el delegado de la aplicación:

MyController *controller = [[MyController alloc] initWithNibName:@"MyController" bundle:nil]; 
[window setContentView:[controller view]]; 

Y luego en mi initWithNibName I don' Haga cualquier cosa que no sea llamar a super por el momento.

+0

publicar su código. No está claro cómo está inicializando su controlador de vista. –

Respuesta

71

Al dividir cada vista en su propia punta y usar NSViewController, la forma típica de manejar las cosas es crear una subclase NSViewController para cada una de sus plumillas. El propietario del archivo para cada archivo semilla respectiva estaría fijado para que NSViewController subclase, y que sería conectar la salida view a la vista personalizada en la punta. Luego, en el controlador de vista que controla la vista de contenido de la ventana principal, crea una instancia de cada subclase NSViewController, luego agrega la vista de ese controlador a su ventana.

un poco rápido de código - en este código, llamo a la vista del controlador de contenido principal MainViewController, el controlador de la "barra de herramientas" es TopViewController, y el resto del contenido es ContentViewController

//MainViewController.h 
@interface MainViewController : NSViewController 
{ 
    //These would just be custom views included in the main nib file that serve 
    //as placeholders for where to insert the views coming from other nibs 
    IBOutlet NSView* topView; 
    IBOutlet NSView* contentView; 
    TopViewController* topViewController; 
    ContentViewController* contentViewController; 
} 

@end 

//MainViewController.m 
@implementation MainViewController 

//loadView is declared in NSViewController, but awakeFromNib would work also 
//this is preferred to doing things in initWithNibName:bundle: because 
//views are loaded lazily, so you don't need to go loading the other nibs 
//until your own nib has actually been loaded. 
- (void)loadView 
{ 
    [super loadView]; 
    topViewController = [[TopViewController alloc] initWithNibName:@"TopView" bundle:nil]; 
    [[topViewController view] setFrame:[topView frame]]; 
    [[self view] replaceSubview:topView with:[topViewController view]]; 
    contentViewController = [[ContentViewController alloc] initWithNibName:@"ContentView" bundle:nil]; 
    [[contentViewController view] setFrame:[contentView frame]]; 
    [[self view] replaceSubview:contentView with:[contentViewController view]]; 
} 

@end 
+0

Funciona como un encanto. ¡Gracias por el ejemplo y también por la explicación completa! – jbrennan

+0

Gracias, esto fue muy útil. ++ – ttvd

2

¿No debería MainViewController ser una subclase de NSWindowController? ¿Y las tomas de corriente de la clase se conectaron para ver elementos en la ventana principal en MainMenu.xib? esperanza Vamos hilos de edad se siguen leyendo ...

+1

No es necesario. En mi opinión, incluso es una buena práctica separar un controlador de ventana del controlador de vista que gestiona la vista de contenido de toda la ventana. Una ventana tiene muchas más partes y funcionalidad que una vista (con un controlador de vista correspondiente). –

Cuestiones relacionadas