无法删除UITextField中的所有字符

时间:2018-08-16 18:49:51

标签: ios swift uitextfield

在我的应用程序中,可以添加事务。事务具有一个称为金额的属性,该属性为Double。我已经实现了添加负数和正数的功能。我使用UISegmentedControll进行此操作。如果用户将金额设置为负数,则amountTextField.text变为““-” + amountTextField.text。用户只能输入Doubles,我添加了此功能:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let oldText = textField.text, let r = Range(range, in: oldText) else{
            return true
        }
        let newText = oldText.replacingCharacters(in: r, with: string)
        let isNumeric = newText.isEmpty || (Double(newText) != nil)
        let numberOfDots = newText.components(separatedBy: ".").count - 1

        let numberOfDecimalDigits: Int
        if let dotIndex = newText.index(of: "."){
            numberOfDecimalDigits = newText.distance(from: dotIndex, to: newText.endIndex) - 1
        } else {
            numberOfDecimalDigits = 0
        }
        return isNumeric && numberOfDots <= 1 && numberOfDecimalDigits <= 2
    }

在正Double前面有一个负号时,不可能删除字符串的第一个数字。例如,如果amountTextField.text是-399.99,并且用户根据需要多次按下Delete按钮,则textField将显示-3。在调试工作中,我发现添加到代码中的函数是这样做的原因。

如何解决此问题?

1 个答案:

答案 0 :(得分:1)

这是一种方法:

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    guard let oldText = textField.text, let r = Range(range, in: oldText) else {
        return true
    }

    let newText = oldText.replacingCharacters(in: r, with: string)

    if newText == "-" {
        // result will be "-" so just
        return true
    }

    let isNumeric = newText.isEmpty || (Double(newText) != nil)
    let numberOfDots = newText.components(separatedBy: ".").count - 1

    let numberOfDecimalDigits: Int
    if let dotIndex = newText.index(of: "."){
        numberOfDecimalDigits = newText.distance(from: dotIndex, to: newText.endIndex) - 1
    } else {
        numberOfDecimalDigits = 0
    }


    if isNumeric && numberOfDots <= 1 && numberOfDecimalDigits <= 2 {
        // value passes those tests, so make sure the leading "-" is still there
        // if not, prepend it, set the text and return false
        if newText.first != "-" {
            textField.text = "-" + newText
            return false
        }
    }

    return isNumeric && numberOfDots <= 1 && numberOfDecimalDigits <= 2
}

我们还有另外两个if块需要处理:

  • 用户移动插入点以删除“-”
  • 用户执行“全选”并点按新数字或删除或粘贴值

我希望您已经知道,如果分段控件处于负数位置,则还需要布尔检查以不同的方式处理此问题。