Comment sélectionner un NSCell dans un NSTableView?
-
03-10-2019 - |
Question
J'ai une petite NSTableView
avec une case à cocher. Chaque fois que la case n'est pas cochée, je veux un des NSCell
s adjacents à grisés et inaccessibles.
Cependant, je ne peux pas comprendre comment traiter une seule cellule spécifique. -dataCellForRow
de NSTableColumn
change toujours la cellule de modèle pour la colonne du tableau entier.
Comment puis-je accéder à une seule cellule?
Edit:. Je remplis la vue du tableau en utilisant le protocole NSTableViewDataSource
La solution
Vous ne « accéder à une cellule ». NSTableView
demande des données uniquement en cas de besoin, vous ne remplissez pas ou contrôler directement.
Au lieu de cela, vous créez un objet contrôleur qui met en oeuvre les protocoles NSTableViewDatasource
et éventuellement NSTableViewDelegate
. La vue de la table envoie ensuite les messages de source de données à votre contrôleur et vos fournitures de contrôleur les données appropriées.
Vous pouvez autoriser la modification d'un objet affiché dans la vue de la table en mettant en œuvre la méthode DataSource ‑tableView:setObjectValue:forTableColumn:row:
. Cette méthode est appelée sur votre objet contrôleur lorsque l'utilisateur clique sur la case à cocher. Il est de la responsabilité de votre contrôleur pour mettre à jour le modèle approprié.
Lorsque le modèle est mis à jour, votre contrôleur doit dire la vue de la table pour reload. La table sera alors demander à votre contrôleur pour la valeur d'une cellule qui nécessite l'affichage en utilisant la méthode DataSource ‑tableView:objectValueForTableColumn:row:
. Cela comprendra la cellule que vous devez désactiver. Vos besoins de contrôleur pour fournir la valeur appropriée pour la cellule.
Si vous avez besoin de plus de contrôle de la cellule, vous pouvez mettre en œuvre la
Procédé délégué ‑tableView:willDisplayCell:forTableColumn:row:
. Ceci est appelé juste avant une cellule est affiché, et vous pouvez modifier la cellule appropriée.
En savoir plus sur l'utilisation de sources de données est en la documentation .
L'autre option (au lieu d'utiliser une source de données) est d'utiliser Cocoa et un Manchettes NSArrayController
qui vous lient à votre collection d'objets de modèle. Dans ce cas, vous pouvez lier la Enabled
liaison de la colonne de table pour une propriété de votre objet modèle qui contrôle l'état activé de la cellule. Il vous incombe de veiller à ce que l'état de cette propriété est correcte.
Si vous avez besoin pour rendre la propriété en fonction de la valeur d'une autre propriété, vous pouvez utiliser le mécanisme clé dépendant décrit dans la section documentation de valeur-clé d'observation.
Autres conseils
Pouvez-vous lier la colonne éditabilité de cette à la valeur qui est affichée dans la case? à savoir si elle est cochée, il est modifiable, sinon ce n'est pas?
Je suis en train de se rappeler l'interface de l'éditeur exacte, et je ne suis pas à côté de mon Mac à la maison, donc je ne suis pas en mesure de faire une promenade totale à travers sur elle -. Espère que cela peut vous orienter dans la bonne direction
Depuis SDK version 10.7, il y a -viewAtColumn:row:makeIfNecessary:
sur NSTableView
. La plupart des informations que je trouve sur le Web ne prennent pas les nouvelles méthodes en compte, si elle est ici pour tous les autres à la recherche d'une réponse à cette question.
De Souris Event à la cellule de sélection
Tout d'abord, ajouter un protocole pour votre contrôleur à la sélection des cellules poignée d'une vue de la table, comme ceci:
@protocol XYZCellSelectionDelegate <NSObject>
- (void)cellViewWasSelectedAtRow:(NSInteger)row column:(NSInteger)column;
@end
Ensuite, la sous-classe NSTableView
et override -mouseDown:
// In your Custom Table View subclass:
- (void)mouseDown:(NSEvent *)event
{
NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
NSInteger selectedRowIndex = [self rowAtPoint:point];
NSInteger selectedColumnIndex = [self columnAtPoint:point];
if ([self.calendarViewDelegate respondsToSelector:@selector(cellViewWasSelectedAtRow:column:)])
{
[self.calendarViewDelegate cellViewWasSelectedAtRow:selectedRowIndex column:selectedColumnIndex];
}
[super mouseDown:event];
}
Ensuite, vous pouvez utiliser -viewAtColumn:row:makeIfNecessary:
comme celui-ci dans l'objet délégué / contrôleur:
- (void)cellViewWasSelectedAtRow:(NSInteger)row column:(NSInteger)column
{
NSView *selectedView = [self.tableView viewAtColumn:column row:row makeIfNecessary:YES];
// Do something with the cell to the right
NSInteger nextColumn = column + 1;
NSView *cellNextToIt = [self.calendarTableView viewAtColumn:nextColumn row:row makeIfNecessary:YES];
}
Remarque:. Aujourd'hui, je passe la vue de la table au délégué en tant que paramètre au lieu de compter sur le délégué de conserver une référence à la vue de la table