Reactivecocoa: NSControl -rac_textSignal ne fonctionne pas lors de la définition de texte par programme

Créé le 27 août 2013  ·  8Commentaires  ·  Source: ReactiveCocoa/ReactiveCocoa

Si je place du texte sur un NSTextField par programme via -setStringValue: ou -setAttributedStringValue: , cela ne déclenche pas NSControlTextDidChangeNotification , ce qui signifie que -rac_textSignal gagné Je ne prends pas la monnaie non plus. Cela ne fonctionne que lorsque le texte est en cours d'édition par interaction de l'utilisateur.

Une solution simple serait d'utiliser -rac_signalForSelector: pour intercepter également les appels aux setters (en plus de vous inscrire pour NSControlTextDidChangeNotification ). D'autres idées?

question

Commentaire le plus utile

Je sais que cela est fermé depuis longtemps, mais j'ai trouvé une solution à votre problème @indragiek.
Supposons que vous ayez une propriété, NSString* name sur votre viewModel.
Dans votre contrôleur de vue, lors de la liaison du champ de texte au modèle de vue et vice versa, procédez comme suit:
[[RACSignal merge:@[self.nameField.rac_textSignal, RACObserve(self.nameField, text)]]<br i="9"/> subscribeNext:^(NSString* text){<br i="10"/> self.viewModel.name = text;<br i="11"/> }];`

De cette façon, vous détectez chaque fois que le signal de texte se déclenche ET pour les modifications programmatiques de la propriété de texte.

Tous les 8 commentaires

La cohérence avec AppKit ici est une fonctionnalité, pas un bogue. Ce serait bizarre, OMI, que rac_textSignal se déclenche pour des événements qui ne sont pas observables par convention.

Cela n'a pas toujours de sens, mais en général, les événements qui se propagent à la couche de vue doivent être considérés comme «finaux». Si vous avez besoin de les filtrer ou de les transformer avant ce point, cela doit être fait via un modèle de vue ou quelque chose du genre.

Quel est le cas d'utilisation de l'observation des changements programmatiques?

Exemple spécifique: j'ai un formulaire avec plusieurs champs de texte et un bouton Effacer, cliquer sur Effacer définit stringValue sur chaque champ de texte à @"" . J'utilise rac_textSignal pour une logique de validation de formulaire, et l'état de validation n'est pas mis à jour lorsque vous cliquez sur Effacer car -rac_textSignal ne prend pas en compte les modifications. La seule solution de contournement est de publier manuellement NSControlTextDidChangeNotification , ce qui est une chose horrible à faire: trollface:

En termes de MVVM , la conception correcte serait d'effectuer une validation sur le _ modèle de vue_, pas sur la vue. Le modèle de vue aurait des liaisons bidirectionnelles avec les champs de texte. Ensuite, le bouton Effacer peut réinitialiser les champs du modèle de vue, et tout est: sparkles :.

MVC serait assez similaire, juste avec un contrôleur de vue intermédiaire ou un modèle à la place.

J'avais pensé à cela, mais l'utilisation de liaisons est un problème en soi dans mon cas particulier. Cela n'a pas de rapport avec cette question, cependant, je pense que cela peut être clos. Merci!

FWIW, même si Cocoa Bindings ™ est un problème, vous pouvez utiliser RACChannel pour créer vos propres liaisons bidirectionnelles qui n'en dépendent pas.

Je sais que cela est fermé depuis longtemps, mais j'ai trouvé une solution à votre problème @indragiek.
Supposons que vous ayez une propriété, NSString* name sur votre viewModel.
Dans votre contrôleur de vue, lors de la liaison du champ de texte au modèle de vue et vice versa, procédez comme suit:
[[RACSignal merge:@[self.nameField.rac_textSignal, RACObserve(self.nameField, text)]]<br i="9"/> subscribeNext:^(NSString* text){<br i="10"/> self.viewModel.name = text;<br i="11"/> }];`

De cette façon, vous détectez chaque fois que le signal de texte se déclenche ET pour les modifications programmatiques de la propriété de texte.

@startupthekid merci, ça m'aide.

@startupthekid merci beaucoup!

Cette page vous a été utile?
0 / 5 - 0 notes