基本上我想限制用户在UITextView对象中只输入一个DECIMAL POINT,我还想将ONE DECIMAL POINT之后的数字限制为TWO(即两位小数)。我正在使用以下代码,该代码目前可用于阻止用户输入多个DECIMAL POINT:
//以下扩展名基本上计算字符串中特定字符的数量:
extension String {
func countInstances(of stringToFind: String) -> Int {
var stringToSearch = self
var count = 0
while let foundRange = stringToSearch.range(of: stringToFind, options: .diacriticInsensitive) {
stringToSearch = stringToSearch.replacingCharacters(in: foundRange, with: "")
count += 1
}
return count
}
}
class ViewController: UIViewController, UITextViewDelegate, UIPopoverPresentationControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.indicativeDesignWorkingLifeTextView.delegate = self
indicativeDesignWorkingLifeTextView.keyboardType = .decimalPad
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
let decimalCount = indicativeDesignWorkingLifeTextView.text.countInstances(of: ".")
if decimalCount > 0 {
return false
} else {
return true
}
}
}
但是,上述代码的问题在于它限制用户在UITextView中仅输入一个DECIMAL POINT,但它也限制用户在输入小数点后不做任何事情。它甚至不允许用户删除他输入的一个小数点并插入新的小数点或任何其他数字。基本上,只要输入一个小数点,用户就无法编辑UITextView内的任何内容。我怎么能修改这个?并且还限制用户只输入两位小数?
答案 0 :(得分:0)
根据您的使用案例是否允许,我强烈建议您使用keyboardType
提供的受支持的iOS,这样您就不必自己完成所有工作。
indicativeDesignWorkingLifeTextView.keyboardType = .decimalPad
答案 1 :(得分:0)
您的UITextViewDelegate方法名称错误。它必须是
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange,
replacementText text: String) -> Bool
答案 2 :(得分:0)
您可以评估生成的文本并检查其中是否有多个小数点。
例如:
if let newText = (indicativeDesignWorkingLifeTextView.text as NSString!)?
.replacingCharacters(in: range, with: text),
newText.components(separatedBy:".").count > 2
{ return false }
出于某种原因,Apple决定为子字符串而不是Swift类型(Range< String.Index>)传递一个旧的NSRange类型,需要对NSString进行笨重的类型转换!否则,这种情况会更加清晰和清晰。
如果您希望整个条件仅允许十进制字符,小数点后不超过一个小数点和最多2位数,则可以将它组合成:
if let newText = (textView.text as NSString!)?.replacingCharacters(in: range, with: text),
case let parts = newText.components(separatedBy:"."),
parts.count > 2
|| text.characters.contains(where:{ !"01234567890.".characters.contains($0) })
|| parts.count == 2 && parts[1].characters.count > 2
{ return false }