Reactivecocoa: NSControl -rac_textSignalは、プログラムでテキストを設定するときに機能しません

作成日 2013年08月27日  ·  8コメント  ·  ソース: ReactiveCocoa/ReactiveCocoa

-setStringValue:または-setAttributedStringValue:を介してプログラムでNSTextFieldテキストを設定した場合、これはNSControlTextDidChangeNotificationトリガーしません。つまり、 -rac_textSignalが勝ちました。変化も拾わないでください。 これは、テキストがユーザーの操作によって編集されている場合にのみ機能します。

簡単な修正は、 -rac_signalForSelector:を使用して、セッターへの呼び出しもインターセプトすることです( NSControlTextDidChangeNotification登録に加えて)。 他のアイデアはありますか?

question

最も参考になるコメント

私はこれが長い間閉鎖されていることを知っていますが、私はあなたの問題の解決策を@indragiekで見つけました。
viewModelにNSString* nameというプロパティがあるとします。
ビューコントローラで、テキストフィールドをビューモデルにバインドするとき、またはその逆の場合は、次のようにします。
[[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"/> }];`

このようにして、テキスト信号が発生するたびに検出し、テキストプロパティをプログラムで変更します。

全てのコメント8件

ここでのAppKitとの一貫性は機能であり、バグではありません。 IMO、これまで観察できなかったイベントに対してrac_textSignalが発生するのは奇妙なことです。

これは必ずしも意味があるとは限りませんが、通常、ビューレイヤーに伝播するイベントは「最終」と見なす必要があります。 そのポイントの前にそれらをフィルタリングまたは変換する必要がある場合は、ビューモデルまたはそれらの線に沿った何かを介して実行する必要があります。

プログラムによる変更を観察するためのユースケースは何ですか?

具体的な例:複数のテキストフィールドと[クリア]ボタンがあるフォームがあります。[クリア]をクリックすると、すべてのテキストフィールドのstringValue@""ます。 一部のフォーム検証ロジックにrac_textSignalを使用していますが、 -rac_textSignalが変更を取得しないため、[クリア]をクリックしても検証ステータスが更新されません。 唯一の回避策は、手動でNSControlTextDidChangeNotification投稿することです。これは、:trollface:を実行するのは恐ろしいことです。

MVVMに関しては、正しい設計は、ビューではなく、_ビューモデル_に対して検証を実行することです。 ビューモデルには、テキストフィールドへの双方向のバインディングがあります。 次に、[クリア]ボタンでビューモデルのフィールドをリセットできます。すべてが:

MVCはかなり似ていますが、代わりに中間のViewControllerまたはモデルを使用します。

私はそれを考えていましたが、私の特定のケースでは、バインディングの使用自体が問題です。 しかし、それはこの質問とは無関係なので、これを閉じることができると思います。 ありがとう!

FWIW、CocoaBindings™が問題である場合でも、 RACChannelを使用して、それに依存しない独自の双方向バインディングを構築できます。

私はこれが長い間閉鎖されていることを知っていますが、私はあなたの問題の解決策を@indragiekで見つけました。
viewModelにNSString* nameというプロパティがあるとします。
ビューコントローラで、テキストフィールドをビューモデルにバインドするとき、またはその逆の場合は、次のようにします。
[[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"/> }];`

このようにして、テキスト信号が発生するたびに検出し、テキストプロパティをプログラムで変更します。

@startupthekidありがとう、それは私のために役立ちます。

@startupthekidありがとう

このページは役に立ちましたか?
0 / 5 - 0 評価