UITextField undo crash

Code Block
*** Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'


reproducing this bug is really easy. Create a new project. add a textfield. set delegate.

Code Block
extension ViewController: UITextFieldDelegate {
   
  func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    let str = (textField.text! + string)
    if str.count <= 30 {
      return true
    }
    return false
  }
}


run the app in ipad and type "abcdef" and copy the text. and paste it 3 or 4 times till limit reached (30 char). And tap undo. CRASHED

Please provide a solution for this. Thanks

Replies

I think this crash may be caused by a bug. If you have "abcdef" and then undo "abcdef" it tries to replace the range with empty strings. It should be doing this on range (5, 0), however, it is trying to do it from (10, 5), which doesn't exist, thus the out of index crash.

As a work around, you could change your code to look like:

Code Block swift
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        guard let text = textField.text else { return true }
        let str = text + string
        if str.count <= 30 {
            if (string.isEmpty && range.length > 0) {
                textField.text = text.count > range.length ? String(text.dropLast(range.length)) : ""
                return false
            }
            return true
        }
        return false
    }


This will still allow the undo function to work, while preventing any crashes. Hope this helps!
  • It does work in undo situation, but 'string.isEmpty && range.length > 0' also matches when I delete a charactor by keyboard. When it matches delete charactors, 'editingChanged' event will not trigger.

Add a Comment
Pressing undo button several time again crashing

Code Block
* Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'
* First throw call stack:
(
0  CoreFoundation           0x00007fff23e3de6e exceptionPreprocess + 350
1  libobjc.A.dylib           0x00007fff512539b2 objc_exception_throw + 48
2  Foundation             0x00007fff25a12215 -[NSMutableRLEArray deleteObjectsInRange:] + 0
3  Foundation             0x00007fff25a10c98 -[NSConcreteMutableAttributedString replaceCharactersInRange:withAttributedString:] + 314
4  UIFoundation            0x00007fff487ddfb4 71-[NSConcreteTextStorage replaceCharactersInRange:withAttributedString:]_block_invoke + 47
5  UIFoundation            0x00007fff487ddb62 NSConcreteTextStorageLockedForwarding + 44
6  UIFoundation            0x00007fff487ddf7f -[NSConcreteTextStorage replaceCharactersInRange:withAttributedString:] + 74
7  UIFoundation            0x00007fff487dbfa9 -[NSTextStorage coordinateEditing:] + 35
8  UIKitCore              0x00007fff496515a5 -[_UITextUndoOperationReplace undoRedo] + 418
9  Foundation             0x00007fff259d384c -[_NSUndoStack popAndInvoke] + 173
10 Foundation             0x00007fff259d1c72 -[NSUndoManager undoNestedGroup] + 296
11 UIKitCore              0x00007fff495d3df4 -[UISystemDefaultTextInputAssistantItem performSystemButtonActionForStyle:] + 628
12 UIKitCore              0x00007fff49326c1d -[UIApplication sendAction:to:from:forEvent:] + 83
13 TextInputUI             0x00007fff481bf4a7 -[TUIAssistantButtonBarView _didTapButtonBarButton:withEvent:] + 356
14 UIKitCore              0x00007fff49326c1d -[UIApplication sendAction:to:from:forEvent:] + 83
15 UIKitCore              0x00007fff48cd5baa -[UIControl sendAction:to:forEvent:] + 223
16 UIKitCore              0x00007fff48cd5ef2 -[UIControl _sendActionsForEvents:withEvent:] + 396
17 UIKitCore              0x00007fff48cd4e63 -[UIControl touchesEnded:withEvent:] + 497
18 UIKitCore              0x00007fff49362508 -[UIWindow _sendTouchesForEvent:] + 1359
19 UIKitCore              0x00007fff4936428d -[UIWindow sendEvent:] + 4501
20 UIKitCore              0x00007fff4933e6d1 -[UIApplication sendEvent:] + 356
21 UIKitCore              0x00007fff493c94ce dispatchPreprocessedEventFromEventQueue + 7628
22 UIKitCore              0x00007fff493cc692 handleEventQueueInternal + 6584
23 UIKitCore              0x00007fff493c2f35 handleHIDEventFetcherDrain + 88
24 CoreFoundation           0x00007fff23da1c91 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
25 CoreFoundation           0x00007fff23da1bbc CFRunLoopDoSource0 + 76
26 CoreFoundation           0x00007fff23da1394 CFRunLoopDoSources0 + 180
27 CoreFoundation           0x00007fff23d9bf8e CFRunLoopRun + 974
28 CoreFoundation           0x00007fff23d9b8a4 CFRunLoopRunSpecific + 404
29 GraphicsServices          0x00007fff38c39bbe GSEventRunModal + 139
30 UIKitCore              0x00007fff49325968 UIApplicationMain + 1605
31 test                0x000000010398c18b main + 75
32 libdyld.dylib            0x00007fff520ce1fd start + 1
)
libcabi.dylib: terminating with uncaught exception of type NSException

  • I have the same problem. Have you solved it yet?

Add a Comment

i also have the same problem. seems it's an iOS bug