Pregunta

Creé con éxito una NSCollectionView y agregué una etiqueta al prototipo de vista en IB, vinculada a una propiedad de mi objeto representado. Ahora quiero crear programáticamente un NSButton y NSTextField con el NSTextField vinculado a una propiedad de mi objeto representado. Cuando se hace clic en el botón, quiero mostrar y ocultar el NSTextField.

El problema con el que me he encontrado es que si pongo mi código de inicialización para mis controles en el método initWithCoder de la vista y el enlace en el wakekeFromNib de la vista, el enlace no se engancha. Si pongo la inicialización de mis controles en el wakekeFromNib, cuando hago clic en el botón, no tengo acceso a los controles en mi vista (son nulos cuando se imprimen usando NSLog).

Por lo que puedo decir, parece que el problema puede ser que la forma en que funciona NSCollectionView es, crea una instancia de la vista, luego la copia para la cantidad de objetos que hay en la vista de colección. ¿Cómo consigo que se inicialicen los botones y que el enlace funcione con la copia del prototipo?

A continuación se muestra mi código de inicialización y mi enlace en el wakekefromNib para mi vista subclasificada:

SubView.h

@interface SubView : NSView {
    NSButton *button;
    NSTextField *textField;
    IBOutlet NSCollectionViewItem *item; // Connected in IB to my NSCollectionViewItem
}

- (IBAction)buttonClicked:(id)sender;

@end

SubView.m

@implementation SubView

- (id)initWithCoder:(NSCoder *)decoder
{
    id view = [super initWithCoder:decoder];

    button = [[NSButton alloc] initWithFrame:NSMakeRect(50, 95, 100, 20)];
    [button setTitle:@"Begin Editing"];
    [button setTarget:self];
    [button setAction:@selector(buttonClicked:)];
    [self addSubview:button];

    textField = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 10, 100, 75)];
    [self addSubview:textField];

    return(view);
}

- (void)awakeFromNib
{   
        // Bind the textField to the representedObject's name property
        [textField bind:@"value" 
       toObject:item 
        withKeyPath:@"representedObject.name" 
        options:nil];
}

- (IBAction)buttonClicked:(id)sender
{
    [button setTitle:@"End Editing"];
    [textField setHidden:YES];
}

@end
¿Fue útil?

Solución

Esto suena similar a algo que acabo de hacer, así que tal vez sea lo que necesitas.

Subclase NSCollectionView y anula:

- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object

En newItemForRepresentedObject: , recupere el elemento de vista, luego agregue sus controles y cualquier enlace programático:

@implementation NSCollectionViewSubclass

- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object {

    // Allow the superclass to create or copy the collection view item
    NSSCollectionViewItem *newItem = [super newItemForRepresentedObject:object];

    // Get the new item's view so you can mess with it
    NSView *itemView = [newItem view];

    //
    // add your controls to the view here, bind, etc
    //

    return newItem;
}

@end

Esperemos que este sea un lugar cercano a donde necesitas estar ...

Otros consejos

-awakeFromNib no se llama en la vista para un NSCollectionViewItem si esa vista está en la misma punta que NSCollectionView, pero se llama si coloca la vista en una punta separada.

  • Cree un archivo de plumín vacío (BlahBlahCollectionViewItem.nib).
  • Recorta la vista del elemento de la colección de cualquier plumín que tengas
  • Pegarlo en el nuevo archivo plumín
  • Cambie la clase de su propietario a NSCollectionViewItem.
  • Conecte la vista de salida del propietario a la vista recién pegada
  • Abra el archivo plumín que contiene NSViewController
  • Seleccione el NSViewControllerItem asociado
  • Cambie su propiedad Nib Name por el nombre de la nueva plumilla
  • Mantenga su código en -awakeFromNib

-awakeFromNib no se llama para las vistas copiadas del prototipo NSCollectionViewItem. Pon tu código de enlace en initWithCoder: y estarás bien.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top