听写后用三指点击执行撤消时应用程序崩溃
App crashes when performing Undo with three finger tap after Dictation
我遇到了问题。鉴于我有一个 UITextField 和一个用于删除文本字段内容的按钮。
所以这按预期工作:
- 使用键盘输入文字
- 点击删除按钮
- 用三个手指点击并select从上下文菜单撤消
- 文本重新出现
现在使用听写时事情开始变得奇怪了:
- 点击听写按钮
- 说一些词,使它们出现在文本字段中
- 点击删除按钮
- 用三个手指点击并select从上下文菜单撤消
- 应用程序崩溃
崩溃是Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'
所以听写的文本似乎并没有出现在可能的撤消列表中。有没有人知道如何解决这个问题?
到目前为止我尝试了什么:
- 使用基本代码清理应用程序以进行验证(请参阅本文末尾的代码 post)
- 创建 UITextField 的子类以覆盖
func dictationRecordingDidEnd()
并使用文本注册新的撤消
- 挠头想知道为什么
我很乐意在这里找到解决方案!
测试应用的代码示例:
import UIKit
class ViewController: UIViewController {
let textField = UITextField(frame: CGRect(x: 50, y: 50, width: 200, height: 44))
override func viewDidLoad() {
super.viewDidLoad()
textField.layer.borderColor = UIColor.black.cgColor
textField.layer.borderWidth = 1
view.addSubview(textField)
let deletebutton = UIButton(type: .custom)
deletebutton.frame = CGRect(x: 50, y: 100, width: 100, height: 50)
deletebutton.addTarget(self, action: #selector(deleteText(_:)), for: .touchUpInside)
deletebutton.setTitle("delete", for: .normal)
deletebutton.setTitleColor(.black, for: .normal)
view.addSubview(deletebutton)
}
@objc func deleteText(_ sender: UIButton) {
textField.text = nil
}
}
更新 1
我现在通过设置 textField.clearButtonMode = .whileEditing
将清除按钮添加到文本字段,这按预期工作。
所以主要问题是:内置清除按钮与自定义按钮有什么不同?是否触发了某些通知?其他魔法?请赐教!
更新 2
执行此操作时应用程序也会崩溃:
- 口述某事
- 使用
textField.text = "Something"
将文本替换为不同的文本
- 三指点击并select撤消
既然没有答案,我会在找到解决方案后回答。
我无法回答为什么会发生这种情况,但这种行为会使 App Store 中广泛使用和可用的应用程序崩溃似乎很常见。
无论如何,以下代码将防止崩溃并基于列出的答案here:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else {
return true
}
let str = text + string
guard str.count > 0 else {
return false
}
if string.isEmpty && range.length > 0 {
textField.text = text.count > range.length ? String(text.dropLast(range.length)) : ""
return false
}
return true
}
我很乐意帮助其他人回答这个问题!
我遇到了问题。鉴于我有一个 UITextField 和一个用于删除文本字段内容的按钮。
所以这按预期工作:
- 使用键盘输入文字
- 点击删除按钮
- 用三个手指点击并select从上下文菜单撤消
- 文本重新出现
现在使用听写时事情开始变得奇怪了:
- 点击听写按钮
- 说一些词,使它们出现在文本字段中
- 点击删除按钮
- 用三个手指点击并select从上下文菜单撤消
- 应用程序崩溃
崩溃是Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'
所以听写的文本似乎并没有出现在可能的撤消列表中。有没有人知道如何解决这个问题? 到目前为止我尝试了什么:
- 使用基本代码清理应用程序以进行验证(请参阅本文末尾的代码 post)
- 创建 UITextField 的子类以覆盖
func dictationRecordingDidEnd()
并使用文本注册新的撤消 - 挠头想知道为什么
我很乐意在这里找到解决方案!
测试应用的代码示例:
import UIKit
class ViewController: UIViewController {
let textField = UITextField(frame: CGRect(x: 50, y: 50, width: 200, height: 44))
override func viewDidLoad() {
super.viewDidLoad()
textField.layer.borderColor = UIColor.black.cgColor
textField.layer.borderWidth = 1
view.addSubview(textField)
let deletebutton = UIButton(type: .custom)
deletebutton.frame = CGRect(x: 50, y: 100, width: 100, height: 50)
deletebutton.addTarget(self, action: #selector(deleteText(_:)), for: .touchUpInside)
deletebutton.setTitle("delete", for: .normal)
deletebutton.setTitleColor(.black, for: .normal)
view.addSubview(deletebutton)
}
@objc func deleteText(_ sender: UIButton) {
textField.text = nil
}
}
更新 1
我现在通过设置 textField.clearButtonMode = .whileEditing
将清除按钮添加到文本字段,这按预期工作。
所以主要问题是:内置清除按钮与自定义按钮有什么不同?是否触发了某些通知?其他魔法?请赐教!
更新 2
执行此操作时应用程序也会崩溃:
- 口述某事
- 使用
textField.text = "Something"
将文本替换为不同的文本
- 三指点击并select撤消
既然没有答案,我会在找到解决方案后回答。
我无法回答为什么会发生这种情况,但这种行为会使 App Store 中广泛使用和可用的应用程序崩溃似乎很常见。
无论如何,以下代码将防止崩溃并基于列出的答案here:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else {
return true
}
let str = text + string
guard str.count > 0 else {
return false
}
if string.isEmpty && range.length > 0 {
textField.text = text.count > range.length ? String(text.dropLast(range.length)) : ""
return false
}
return true
}
我很乐意帮助其他人回答这个问题!