2011-12-13 12 views
9

¿Hay algún tipo de ID que se pueda usar y establecer en .nib/.xib a través de Xcode que se pueda consultar en tiempo de ejecución para identificar una instancia de vista particular del código?ID único en NSViews

En particular, al tener varias copias de la misma subclase NSView en nuestra interfaz, ¿cómo podemos saber cuál estamos mirando actualmente?

Respuesta

9

Los objetos genéricos NSView no pueden tener su propiedad tag en Interface Builder. El método tag en NSView es un método de solo lectura y solo se puede implementar en las subclases de NSView. NSView no implementa un método setTag:.

Sospecho que las otras respuestas se refieren a instancias de NSControl que define un método -setTag: y tiene un campo de Generador de interfaz para permitirle establecer la etiqueta.

Lo que puede hacer con vistas genéricas es utilizar atributos de tiempo de ejecución definidos por el usuario. Esto le permite preestablecer los valores de las propiedades en su objeto de vista. Así que si su vista define una propiedad de este modo:

@property (strong) NSNumber* viewID; 

Luego, en la sección de atributos definidos por el usuario del inspector de la identidad en el Interface Builder, se podría añadir una propiedad con la ruta de acceso clave viewID, el tipo Number y el valor 123 .

En el método -awakeFromNib de su vista, puede acceder al valor de la propiedad. Encontrará que en el ejemplo anterior, la propiedad viewID de su vista se habrá preconfigurado en 123.

+0

¡Eso suena muy bien, gracias por la pista! Voy a intentar eso. Por desgracia, nada predefinido en el vainilla Cocoa NSView que se puede usar, pero supongo que todavía estoy pensando demasiado en una forma PowerPlant/MFC ;-) – Jay

+1

La respuesta a continuación funciona para una vista genérica. Simplemente configure Identifer en xib y acceda a él mediante programación con view.identifier – Colin

+0

¿Alguna idea de cuál es la lógica detrás de la etiqueta que se lee solo en NSView? – Mercurial

10

En Interface Builder, hay una manera de establecer el "identificador" de un NSView. En este caso, usaré el identificador "54321" como la cadena identificadora.

NSView Se ajusta al NSUserInterfaceItemIdentification Protocol, que es un identificador único como NSString. Podría recorrer la jerarquía de vistas y encontrar el NSView con ese identificador.

Por lo tanto, para construir en este post sobre cómo obtener la lista de NSViews, Get ALL views and subview of NSWindow, entonces podría encontrar el NSView con el identificador que desee:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    NSView *viewToFind = [self viewWithIdentifier:@"54321"]; 
} 

- (NSView *)viewWithIdentifier:(NSString *)identifier 
{ 
    NSArray *subviews = [self allSubviewsInView:self.window.contentView]; 

    for (NSView *view in subviews) { 
     if ([view.identifier isEqualToString:identifier]) { 
      return view; 
     } 
    } 

    return nil; 
} 

- (NSMutableArray *)allSubviewsInView:(NSView *)parentView { 

    NSMutableArray *allSubviews  = [[NSMutableArray alloc] initWithObjects: nil]; 
    NSMutableArray *currentSubviews = [[NSMutableArray alloc] initWithObjects: parentView, nil]; 
    NSMutableArray *newSubviews  = [[NSMutableArray alloc] initWithObjects: parentView, nil]; 

    while (newSubviews.count) { 
     [newSubviews removeAllObjects]; 

     for (NSView *view in currentSubviews) { 
      for (NSView *subview in view.subviews) [newSubviews addObject:subview]; 
     } 

     [currentSubviews removeAllObjects]; 
     [currentSubviews addObjectsFromArray:newSubviews]; 
     [allSubviews addObjectsFromArray:newSubviews]; 

    } 

    for (NSView *view in allSubviews) { 
     NSLog(@"View: %@, tag: %ld, identifier: %@", view, view.tag, view.identifier); 
    } 

    return allSubviews; 
} 

O, dado que está utilizando una subclase NSView, se podría establecer la "etiqueta" de cada vista en tiempo de ejecución. (O bien, podría establecer el identificador en tiempo de ejecución). Lo bueno de la etiqueta es que hay una función preconstruida para encontrar una vista con una etiqueta específica.

// set the tag 
NSInteger tagValue = 12345; 
[self.myButton setTag:tagValue]; 

// find it 
NSButton *myButton = [self.window.contentView viewWithTag:12345]; 
Cuestiones relacionadas