在iOS 13中,通过shouldChangeCharactersIn
实现UITextfieldDelegate
时,使用滑动键盘时应用程序崩溃。
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text as NSString? {
let txtAfterUpdate = text.replacingCharacters(in: range, with: string)
textField.text = txtAfterUpdate
}
return false
}
这是Apple的错误吗?
答案 0 :(得分:2)
我能够重现此内容-如果您在滑动输入期间更改了UITextField上文本的状态-并且仅在滑动输入期间,它将尝试重新插入滑动的内容(即使您返回false),也会重新触发您的委托事件,这将启动递归循环。
这有点hack,但是您可以用
来捕获它 private var lastEntry: String?
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if string.count > 1 && string == lastEntry { // implies we're swiping or pasting
print("Caught unwanted recursion")
return
}
lastEntry = string
if let text = textField.text as NSString? {
let txtAfterUpdate = text.replacingCharacters(in: range, with: string)
textField.text = txtAfterUpdate
}
return false
}
这将阻止用户连续两次粘贴/滑动相同的东西,但至少在Apple解决问题时,至少可以让用户滑动。
答案 1 :(得分:0)
我使用UIPasteboard识别用户何时粘贴,然后将文本保留为用户使用如下滑动输入的内容:
myFunction()
我还意识到,使用滑动键盘时,TextField仅接受静态字符串。 希望对您有所帮助。
答案 2 :(得分:0)
在设置文本之前,您可以重置委托,然后再次将其设置为 self。 但是如果 textfield 为空,这个解决方案有一个问题 - 文本会翻倍。
Му 代码示例:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let currentText: String = textField.text ?? ""
if #available(iOS 13, *) {
textField.delegate = nil
let resultText = editedText
textField.text = resultText
if currentText.isEmpty, textField.text != resultText {
textField.text = resultText
}
textField.delegate = self
} else {
textField.text = input.result
}
return false
}