无法从 UITextField 中删除所有字符
Cannot delete all characters from a UITextField
在我的应用程序中,可以添加交易。该交易有一个名为 amount 的属性,这个属性是一个 Double。我已经实现了添加负数和正数的功能。我用 UISegmentedControll
来做到这一点。如果用户将金额设为负数,amountTextField.text
将变为“-”+ amountTextField.text。用户可以输入双打我添加了这个功能:
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,并且用户按他想要的次数按删除按钮,textField 将显示 -3。在我的调试工作中,我发现我在代码中添加的功能是造成这种情况的原因。
我该如何解决这个问题?
这是一种方法:
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
块要处理:
- 用户移动插入点以删除“-”
- 用户执行 "select all" 并点击一个新数字或删除,或粘贴一个值
我希望您已经知道,如果分段控件 not 处于负位置,您还需要布尔检查以不同方式处理此问题。
在我的应用程序中,可以添加交易。该交易有一个名为 amount 的属性,这个属性是一个 Double。我已经实现了添加负数和正数的功能。我用 UISegmentedControll
来做到这一点。如果用户将金额设为负数,amountTextField.text
将变为“-”+ amountTextField.text。用户可以输入双打我添加了这个功能:
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,并且用户按他想要的次数按删除按钮,textField 将显示 -3。在我的调试工作中,我发现我在代码中添加的功能是造成这种情况的原因。
我该如何解决这个问题?
这是一种方法:
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
块要处理:
- 用户移动插入点以删除“-”
- 用户执行 "select all" 并点击一个新数字或删除,或粘贴一个值
我希望您已经知道,如果分段控件 not 处于负位置,您还需要布尔检查以不同方式处理此问题。