如何限制 UITextField 中的十进制输入值

How to limit decimal input value in UITextField

我目前正在检查我的 UITextField,它设置为在 shouldChangeCharactersIn 中显示数字小键盘,以将输入限制为仅一个小数点分隔符和 2 个小数点(感谢 this question):

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

    let decimalSeparator = String(Locale.current.decimalSeparator ?? ".")

    if (textField.text?.contains(decimalSeparator))! {

        let limitDecimalPlace = 2
        let decimalPlace = textField.text?.components(separatedBy: decimalSeparator).last

        if (decimalPlace?.count)! < limitDecimalPlace {

            return true

        } else {

           return false

        }

    }

}

效果很好。但是,现在可以插入用户想要的任何值,我想将其限制为低于 999 的值。我曾经检查长度以只允许 3 个字符,但现在我想允许以下值(例如) :

143
542.25
283.02
19.22
847.25

但我不想让:

2222
3841.11
999.99

我该怎么做?

您可能需要两次检查:

  1. 确保是xxx.xx的形式。这种模式匹配通常通过使用正则表达式搜索来实现。

    这里的技巧是确保您支持所有带小数位和不带小数位的排列,其中小数位数为两位或更少,整数位数为三位或更少。

  2. 尝试将其转换为数字并检查该值是否小于 999。

因此:

let formatter = NumberFormatter()

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let candidate = ((textField.text ?? "") as NSString).replacingCharacters(in: range, with: string)
    let separator = formatter.decimalSeparator!

    if candidate == "" { return true }

    let isWellFormatted = candidate.range(of: "^[0-9]{1,3}([\(separator)][0-9]{0,2})?$", options: .regularExpression) != nil

    if isWellFormatted,
        let value = formatter.number(from: candidate)?.doubleValue,
        value >= 0,
        value < 999 {
            return true
    }

    return false
}

注:

  • 我假设您希望用户能够遵守其设备的本地化设置(例如,让德国用户输入 123,45,因为他们使用 , 作为小数点分隔符).

  • 正则表达式,如果你不习惯正则表达式,"^[0-9]{1,3}([\(separator)][0-9]{0,2})?$”可能看起来有点毛茸茸。

    • ^匹配字符串的开头;
    • [0-9]明显匹配任意数字;
    • {1,3}匹配一到三位整数;
    • (...)? 表示“可选,查找以下内容”;
    • 同样,[0-9]{0,2}表示“介于零和两位小数之间;和
    • $匹配字符串的结尾。