NumberFormatter для ввода NSSearchField - PullRequest
       116

NumberFormatter для ввода NSSearchField

0 голосов
/ 02 ноября 2019

У меня есть NSSearchField, где пользователь может вводить число с десятичными знаками для поиска в данных. У меня проблемы с использованием NumberFormatter для отображения правильного формата.

Я добавил это в IB:

enter image description here

Чтопроисходит, как только пользователь вводит десятичную точку (или любой другой локальный символ для этого), поле становится пустым. То же самое происходит, когда я набираю букву (это ожидается), поэтому кажется, что десятичная точка отклоняется, как если бы она была буквой. Конечно, не то, что я хочу.

Пробовал много разных комбинаций этих флажков на полпути (включая «Генерация десятичных чисел»), но не могу заставить его работать.

Если вы посмотрите наобразец внизу рисунка, который выглядит нормально.

И в коде нет ничего, что манипулирует полем поиска.

1 Ответ

0 голосов
/ 12 ноября 2019

Я наконец решил это, полностью отбросив форматтер и просто отфильтровав строку в controlTextDidChange. Обратите внимание, что это работает как для NSTextField, так и для NSSearchField.

class ViewController: NSViewController {
    @IBOutlet var searchField: NSSearchField! // delegate is set in SB

    lazy var decimalCharacterSet: CharacterSet = {
        var charSet = CharacterSet.init(charactersIn: "0123456789")

        charSet.insert(charactersIn: Locale.current.decimalSeparator!)

        return charSet
    }()
}

extension ViewController: NSControlTextEditingDelegate {
    func controlTextDidChange(_ notification: Notification) {
        if let textField = notification.object as? NSTextField {
            // first filter out all the non-numbers
            let chars = textField.stringValue.components(separatedBy: decimalCharacterSet.inverted)
            var result = chars.joined()

            // now check if there are more than one decimal separators
            let count = result.filter { $0 == Character(Locale.current.decimalSeparator!) }.count

            // if so, remove the last character in the string, this is what has just been typed.
            if count > 1 {
                result = String(result.dropLast())
            }

            // finally, assign the filtered string back to the textField
            textField.stringValue = result
         }
    }
}
...