简体   繁体   中英

How to detect the change of UITextField when the button tapped

I'm observing a textfield using combine like this.

extension UITextField {

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

}

(source code from https://cocoacasts.com/combine-fundamentals-observing-a-text-field-with-combine )

And I have a button that make textfield's text nil when pressed.
textPublisher detect keyboard input very well, but when the button is pressed, it doesn't publish anything.

How can I detect the textfield's change when the button pressed?

The text field notification is only broadcast (by default) when the user makes changes. When you make programmatic changes, however, you can simply broadcast the notification yourself.

Here is a Playground. Note that the button action simply uses NotificationCenter.default.post(name:object:) :

import UIKit
import PlaygroundSupport
import Combine

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

let controller = UIViewController()
controller.view.frame = CGRect(x: 0, y: 0, width: 340, height: 480)

let textField = UITextField(frame: CGRect(x: 20, y: 20, width: 300, height: 30))
controller.view.addSubview(textField)
textField.borderStyle = .line

let button = UIButton(frame: CGRect(x:20, y: 70, width: 200, height: 30), primaryAction: UIAction(title: "Push Me", handler: { action in
    textField.text = ""
    NotificationCenter.default.post(name: UITextField.textDidChangeNotification, object: textField)
}))
button.configuration = .bordered()
controller.view.addSubview(button)

let subscription = textField.textPublisher.sink {
    print("There is new text: \($0)")
}

PlaygroundSupport.PlaygroundPage.current.liveView = controller;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM