text
During the process of adapting to iOS 13,UITextField
When entering Chinese, three fingers undo it generates crash.
Bugly reports an error
NSInternalInconsistencyException setGroupIdentifier:: _NSUndoStack 0x1206532f0 is in invalid state, calling setGroupIdentifier with no begin group mark
Stack Information
CoreFoundation ___exceptionPreprocess + 220 objc_exception_throw + 56 Foundation -[_NSUndoStack groupIdentifier] Foundation -[NSUndoManager undoNestedGroup] + 240 UIKitCore -[UIUndoGestureInteraction undo:] + 72 UIKitCore -[UIKBUndoInteractionHUD performDelegateUndoAndUpdateHUDIfNeeded] + 96 UIKitCore -[UIKBUndoInteractionHUD controlActionUpInside:] + 152 UIKitCore -[UIApplication sendAction:to:from:forEvent:] + 96 xxxxx -[UIApplication(MemoryLeak) swizzled_sendAction:to:from:forEvent:] + 288 UIKitCore -[UIControl sendAction:to:forEvent:] + 240 UIKitCore -[UIControl _sendActionsForEvents:withEvent:] + 408 UIKitCore -[UIControl touchesEnded:withEvent:] + 520 UIKitCore -[UIWindow _sendTouchesForEvent:] + 2324 UIKitCore -[UIWindow sendEvent:] + 3352 UIKitCore -[UIApplication sendEvent:] + 336 UIKitCore ___dispatchPreprocessedEventFromEventQueue + 5880 UIKitCore ___handleEventQueueInternal + 4924 UIKitCore ___handleHIDEventFetcherDrain + 108 CoreFoundation ___CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24 CoreFoundation ___CFRunLoopDoSource0 + 80 CoreFoundation ___CFRunLoopDoSources0 + 180 CoreFoundation ___CFRunLoopRun + 1080 CoreFoundation CFRunLoopRunSpecific + 464 GraphicsServices GSEventRunModal + 104 UIKitCore UIApplicationMain + 1936 xxxxx main + 148 _start + 4
Problem positioning
When I didn’t have many ideas, I finally found the problem by commenting on the code.
[self addTarget:observer action:@selector(textChange:) forControlEvents:UIControlEventEditingChanged];
- (void)textChange:(UITextField *)textField { ... ... UITextRange *selectedRange = [textField markedTextRange]; if (!selectedRange || !) { if ( > maxLength) { = [destText substringToIndex:maxLength]; } } }
This code will limit the length of the copy when entered. Three-finger revocation will triggerUIControlEventEditingChanged
Event, executiontextChange
, obtained at this timemarkedTextRange
yesnil
Even if it existsmarkedText
. This leads toUITextField
oftext
It may be modified. If you continue to perform the undo operation after modifying the copy, it will definitely cause crash.
Solution
Add copywriter judge and intercept asynchronously to the main queue, in the nextrunloop
implement.
- (void)textChange:(UITextField *)textField { dispatch_async(dispatch_get_main_queue(), ^{ ... ... }); }
Crash after truncation of numbers
After the digital input limits the length, continue to input after exceeding the length. Undoing will also cause crash, and the above method is not feasible. The current plan isUITextField
The callback method performs input intercept.
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { /// After entering a number, intercepting the string can still trigger the undo operation and cause crash. Intercept it here. if ( == UIKeyboardTypeNumberPad && >= textField.tt_maxLength) { return NO; } return YES; }
The above is the detailed explanation of the example of iOS13 adaptation to three-finger revocation and copywriting limit. For more information about iOS13 adaptation to three-finger revocation, please pay attention to my other related articles!