Search code examples
swiftuitextfieldcombine

where should I adapt combine publisher to monitor UITextfield text changed?


I have customized UITextfield which has clear textfield button on right accessory view. clearbutton has textfield.text.removeAll() or textfield.text = ""

To monitor text changing on this textfield, I have added textPublisher like this.

var textPublisher: AnyPublisher<String, Never> {
    NotificationCenter.default.publisher(
        for: UITextField.textDidChangeNotification,
        object: self
    )
    .compactMap { ($0.object as? UITextField)?.text }
    .eraseToAnyPublisher()
}

I would take UIButton enable assign with textfield text length.

let button = UIButton()

textPublisher.sink { text in
     button.isEnabled = text.count >= 2
}.store(in: &cancellableSet)

This code is worked on UIKeyboardAction but not working on redeclare UITextfield.text programmatically. like clear button action what I added. seems textDidChangeNotification event not fired when I put textfield.text = ""

where should I adapt combine publisher to monitor UITextfield text changed?


Solution

  • This code

    NotificationCenter.default.publisher(
        for: UITextField.textDidChangeNotification,
        object: self
    )
    

    Creates a publisher based on UITextFieldTextDidChangeNotification.

    In this this stack overflow question the panel notes that the UITextFieldTextDidChangeNotification only fires in response to user activity and not when when you change the content of the view using program code with a call like textfield.text = "".

    So your question is really a duplicate of that other question. You are receiving the notification through Combine, but the problem is related to when the notification is sent and Combine is largely irrelevant to that problem.

    One way to solve the problem would be to also send the notification yourself when you change the text programmatically.

    textfield.text = ""
    NotificationCenter.default.post(
        name:UITextField.textDidChangeNotification, object: textfield)