Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 口述后用三个手指轻触执行撤消时,应用程序崩溃_Swift_Uitextfield_Dictation - Fatal编程技术网

Swift 口述后用三个手指轻触执行撤消时,应用程序崩溃

Swift 口述后用三个手指轻触执行撤消时,应用程序崩溃,swift,uitextfield,dictation,Swift,Uitextfield,Dictation,我有个问题。给定我有一个UITextField,一个删除文本字段内容的按钮 因此,这正如预期的那样起作用: 用键盘输入文本 点击删除按钮 用三个手指轻触,然后从关联菜单中选择“撤消” 文本重新出现 现在,当使用听写时,事情开始变得奇怪: 点击听写按钮 说出一些单词,使其出现在文本字段中 点击删除按钮 用三个手指轻触,然后从关联菜单中选择“撤消” 应用程序崩溃 由于未捕获的异常“NSRangeException”,崩溃正在终止应用程序,原因是:“nsmutablerearray replaceOb

我有个问题。给定我有一个UITextField,一个删除文本字段内容的按钮

因此,这正如预期的那样起作用:

  • 用键盘输入文本
  • 点击删除按钮
  • 用三个手指轻触,然后从关联菜单中选择“撤消”
  • 文本重新出现
  • 现在,当使用听写时,事情开始变得奇怪:

  • 点击听写按钮
  • 说出一些单词,使其出现在文本字段中
  • 点击删除按钮
  • 用三个手指轻触,然后从关联菜单中选择“撤消”
  • 应用程序崩溃
  • 由于未捕获的异常“NSRangeException”,崩溃正在终止应用程序,原因是:“nsmutablerearray replaceObjectsInRange:withObject:length::Out-bounds”

    因此,听写的文本似乎不在可能的撤销列表中。有人知道如何解决这个问题吗? 到目前为止,我尝试的是:

    • 使用基本代码清理应用程序以进行验证(请参阅本文末尾的代码)
    • 创建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
    将clear按钮添加到文本字段中,效果与预期一样。 因此,主要的问题是:内置的清除按钮与自定义按钮有什么不同?有人被解雇了吗?还有别的魔法吗?请开导我

    更新2

    执行此操作时,应用程序也会崩溃:

  • 口述
  • 使用
    textField.text=“Something”
  • 用三个手指轻按并选择“撤消”

  • 既然还没有答案,我会在找到解决方案后再回答

    我无法回答为什么会发生这种情况,但这种行为导致应用商店中广泛使用和可用的应用崩溃的情况似乎很常见

    无论如何,以下代码将防止崩溃,并基于列出的答案:

    我很乐意帮助其他人回答这个问题

    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
        }