swiftcocoaappkitnsformatter

How to validate NSTextField content in a modal dialog


My app has a modal dialog with two NSTextFields, and "Cancel" and "OK" buttons on it. The first textfield has a number formatter to ensure you can only enter integers.

I would like to display an alert to the user when they attempt to enter invalid data in the first textfield. This should show when the textfield loses focus, or if they attempt to click the modal's "OK" button.

What I've tried:

Setting up an NSTextFieldDelegate for the textfield:

extension ViewController: NSTextFieldDelegate {
    func control(_ control: NSControl, didFailToFormatString string: String, errorDescription error: String?) -> Bool {
        let alert = NSAlert()
        alert.messageText = "Invalid Number"
        alert.informativeText = error ?? "You must enter a number."
        alert.runModal()

        return true
    }
}

The problem

The code above only kind-of works; when there's invalid data it does show a useful alert when the textfield loses focus but:


Solution

  • clicking the OK button does not trigger the field's formatting and thus the alert does not show.

    Call makeFirstResponder(nil) to force formatting of the contents. makeFirstResponder returns false if the text field refuses to resign its first responder status.

    @IBAction func okAction(_ sender: Any) {
        if let window = view.window,
            window.makeFirstResponder(nil) {
            dismiss(self)
        }
    }