Search code examples
swiftmacosnsnotification

Swift macOS notification on textchange


in my NSViewController I have an NSTexField that fires notifications every time its content changes.

I also have several buttons, that have IBActions defined to write characters to the NSTextField. However everytime one of the buttons is pressed the NSTextField gets updated. The notification is not fired.

How can I manually fire a NSControlTextDidChange event?

override func controlTextDidChange(_ notification: Notification) {
    if let textField = notification.object as? NSTextField {
       filterTable(with: textField.stringValue)
    }
}

@IBAction func pressedKeyButton(_ sender: NSButton) {
    let character = sender.title
    self.searchTextField.stringValue.append(character)
    self.searchTextField.textDidChange(Notification(name:  .NSControlTextDidChange,object: nil))
}

Solution

  • Since this is a Mac app, you can make this much simpler by using Cocoa Bindings to populate the text field. Simply declare a dynamic property on your view controller with a didSet block, like so:

    @objc dynamic var searchString: String = "" {
        didSet { /* put notification code here */ }
    }
    

    Then, in Interface Builder, in the Bindings Inspector, bind the text field's Value binding to the view controller, with "Model Key Path" set to searchString. Also, turn on the "Continuously Updates Value" check box. In your own code, update the text field by altering the searchString property rather than accessing the text field directly (you might even be able to get rid of the outlet for the text field, as you likely won't need it anymore). Since all changes to the string displayed in the text field will now go through the searchString property, its didSet block will always be called, and you will be consistently notified.