Question

J'ai réussi à créer un NSCollectionView et à ajouter une étiquette au prototype de vue dans IB, lié à une propriété de mon objet représenté. Je veux maintenant créer par programme un NSButton et un NSTextField avec le NSTextField lié à une propriété de mon objet représenté. Lorsque le bouton est cliqué, je souhaite afficher et masquer le champ NSText.

Le problème que j'ai rencontré est que si je mets mon code d'initialisation pour mes contrôles dans la méthode initWithCoder de la vue et la liaison dans la propriété awakeFromNib de la vue, la liaison ne sera pas connectée. Si je mets l'initialisation de mes contrôles dans awakeFromNib, lorsque je clique sur le bouton, je n'ai pas accès aux contrôles de ma vue (ils sont nuls lorsqu'ils sont imprimés à l'aide de NSLog).

D'après ce que je peux dire, il semblerait que le problème réside dans le fait que NSCollectionView fonctionne de la manière suivante: il crée une instance de la vue, puis le copie en indiquant le nombre d'objets de la vue de collection. Comment puis-je obtenir les boutons pour initialiser et la liaison pour travailler avec la copie du prototype?

Vous trouverez ci-dessous mon code d'initialisation et ma liaison dans awakeFromNib pour ma vue sous-classée:

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
Était-ce utile?

La solution

Cela ressemble à quelque chose que je viens de faire, alors c'est peut-être ce dont vous avez besoin.

Sous-classe NSCollectionView et une substitution:

- (NSCollectionViewItem *)newItemForRepresentedObject:(id)object

Dans newItemForRepresentedObject: , récupérez l'élément de vue, puis ajoutez vos contrôles et toutes les liaisons de programmation:

@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

J'espère que c'est quelque part près de l'endroit où vous devez être ...

Autres conseils

-awakeFromNib n'est pas appelé dans la vue pour un NSCollectionViewItem si cette vue est dans le même nib que NSCollectionView, mais elle est appelée si vous placez la vue dans un nib séparé.

  • Créez un fichier nib vide (BlahBlahCollectionViewItem.nib).
  • Coupez la vue de l'élément de collection dans la plume que vous avez
  • .
  • Collez-le dans le nouveau fichier nib
  • Modifiez la classe de son propriétaire en NSCollectionViewItem.
  • Connectez la sortie de la vue du propriétaire à la vue nouvellement collée
  • Ouvrez le fichier nib contenant le NSViewController
  • Sélectionnez le NSViewControllerItem associé
  • Remplacez la propriété Nom de la plume par le nom de la nouvelle plume
  • Conservez votre code dans -awakeFromNib

-awakeFromNib n'est pas appelé pour les vues copiées à partir du prototype NSCollectionViewItem. Placez votre code de liaison dans initWithCoder: et tout ira bien.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top