Search code examples
swiftrx-swiftrx-cocoa

Changing the text of a UITextField does not trigger the rx.text binder


I have a UITextField called commentField and I create an Observable<Bool> like this:

let isCommentFieldValid = self.commentField.rx.text.orEmpty.map({ !$0.isEmpty })

This observable determines whether a button is enabled or not. The problem is that when I change the text property of commentField liked this:

self.commentField.text = ""

The isCommentFieldValid doesn't trigger again and, thus, the button's state doesn't change. Any edition using the UI works: if I remove all text from the field through the keyboard, the isCommentFieldValid updates, but via code it doesn't.

Is there a reason this doesn't work?


Solution

  • If you look at the underlying implementation for rx.text you'll see that it relies on the following UIControlEvents: .allEditingEvents and .valueChanged. Explicitly setting the text property on UITextField does not send actions for these events, so your observable is not updated. You could try sending an action explicitly:

    self.commentField.text = ""
    self.commentField.sendActions(for: .valueChanged)