I got a problem. Given I have a UITextField an a button to delete the content of the text field.
So this works as expected:
Now things start to get weird when using dictation:
The crash is Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'
So it seems that the text from the dictation does not end up in the list of possible undos. Does anyone havens idea on how to solve this? What I tried so far:
func dictationRecordingDidEnd()
and registering new undo with the textI would be very happy to have a solution here!
Code Example for testing app:
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
}
}
Update 1
I now added the clear button to the text field by setting textField.clearButtonMode = .whileEditing
and this works as expected.
So the main question is: What does the built in clear button different than a custom one? Is some notification fired? Some other magic? Please enlighten me!
Update 2
The app also crashes when doing this:
textField.text = "Something"
Since there where no answers yet, I will answer it as I found a solution.
I can bot answer why this happens but it seems to be pretty common that this behavior crashes apps which are widely used and available in the App Store.
Anyway, the following code will prevent a crash and is based on the answer listed 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
}
I'm happy to help anyone else with this answer!