2008-10-11 9 views
5

J'ai besoin de savoir quand l'utilisateur a fini d'éditer une cellule dans un NSTableView. La table contient tous les calendriers de l'utilisateur (obtenus à partir de CalCalendarStore), donc pour que les changements de l'utilisateur soient sauvegardés, je dois informer le CalCalendarStore des changements. Cependant, je ne trouve rien qui soit appelé après que l'utilisateur ait fini son édition - je suppose qu'il y aurait une méthode dans le délégué de la table, mais j'en ai vu une qui est appelée quand l'édition commence, pas quand l'édition se termine.Comment puis-je être informé lorsque l'utilisateur a fini de modifier une cellule dans un NSTableView?

Répondre

2

Sous-classe NSTableView et redéfinir textDidEndEditing: (veillez à appeler l'implémentation de super).

Ceci ne sera invoqué que par les champs de texte NSTextFieldCell ou NSComboBoxCell (mais seulement en changeant la valeur en la tapant, pas en sélectionnant la valeur dans le menu du combo).

+0

On dirait que ça va marcher. Merci beaucoup. :) – Andy

1

Regardez dans le protocole NSTableDataSource. Le message que vous recherchez s'appelle: tableView: setObjectValue: forTableColumn: row:

+1

Ceci est probablement la bonne réponse. Cela dit, cela ne fonctionne qu'avec une table à base de cellules. Si vous utilisez une table basée sur les vues, cette méthode n'est jamais appelée. – dgatwood

1

Cela ne semble pas fonctionner dans mon cas. J'ai défini ma classe de contrôleur comme DataSource à la table, mais la méthode n'a jamais été appelée. Les données sont ma table est liée aux valeurs dans un NSArrayController - pourrait-il être pourquoi mon objet n'a pas été appelé?

2

Mettre en place des observateurs pour chaque élément du tableau contenu à l'aide addObserver: toObjectsAtIndexes: forKeyPath: Options: contexte:

Vous aurez également besoin de définir un observateur du tableau lui-même, de sorte que vous serez informé sur les objets qui sont ajoutés ou supprimés du tableau. Pour un exemple, regardez le projet iSpend.

-1

Sous-classe NSArrayController et override objectDidEndEditing: (veillez à appeler l'implémentation de super).

Ceci sera principalement seulement invoqué par les champs de texte NSTextFieldCell ou NSComboBoxCell (mais seulement en changeant la valeur en la tapant, pas en sélectionnant la valeur du menu du combo). Il y aura peut-être quelques autres cellules qui l'invoqueront, mais je ne suis pas sûr de savoir lesquelles. Si vous avez une cellule personnalisée, envisagez d'implémenter les protocoles informels NSEditor et NSEditorRegistration.

14

Vous pouvez obtenir le même résultat sans sous-classement NSTableView en utilisant NSNotificationCenter ou en utilisant les méthodes NSControl. Consultez la documentation d'Apple ici:

http://developer.apple.com/library/mac/#qa/qa1551/_index.html

Il est seulement quelques lignes de code et a parfaitement fonctionné pour moi.


Si vous pouvez être le delegate du NSTableView vous avez juste besoin de mettre en œuvre la méthode

- (void)controlTextDidEndEditing:(NSNotification *)obj { ... } 

En fait, NSTableView est le delegate des NSControl éléments qu'il contient, et transmet les appels de méthode son delegate (Il existe d'autres méthodes qui sont utiles)

Sinon, utilisez le NSNotificationCenter:

// where you instantiate the table view 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(editingDidEnd:) 
    name:NSControlTextDidEndEditingNotification object:nil]; 

// somewhere else in the .m file 
- (void)editingDidEnd:(NSNotification *)notification { ... } 

// remove the observer in the dealloc 
- (void)dealloc { 
    [[NSNotificationCenter defaultCenter] removeObserver:self 
    name:NSControlTextDidEndEditingNotification object:nil]; 
    [super dealloc] 
} 
+1

Eh bien, c'est correct ou faux, selon que vous utilisez des tables basées sur des cellules ou des vues. Si vous utilisez des tables basées sur des cellules et que votre objectif est d'écrire les modifications, cette approche ne fonctionnera pas car cette notification est envoyée * avant * la table: table: setObjectValue: forTableColumn: row: méthode est appelée pour stocker les valeurs dans la source de données, de sorte que vous écrivez les anciennes valeurs. – dgatwood

+0

En fait, je ne reçois pas cette notification du tout dans une vue de table basée sur la vue –

0

Traduire @ réponse de Milly en Swift 3:

// Setup editing completion notifications 
NotificationCenter.default.addObserver(self, selector: #selector(editingDidEnd(_:)), name: NSNotification.Name.NSControlTextDidEndEditing, object: nil) 

fonction pour gérer la notification:

func editingDidEnd(_ obj: Notification) { 
    guard let newName = (obj.object as? NSTextField)?.stringValue else { 
     return 
    } 

    // post editing logic goes here 
}