返回顶部
首页 > 资讯 > 移动开发 >iOS13适配三指撤销和文案限长实例详解
  • 607
分享到

iOS13适配三指撤销和文案限长实例详解

iOS13适配三指撤销文案限长iOS三指撤销文案限长 2023-01-29 15:01:33 607人浏览 薄情痞子
摘要

目录正文Bugly报错堆栈信息问题定位解决方案数字截断后 crash正文 在适配iOS13的过程中,UITextField输入中文的时候三指撤销产生了 crash。 Bugly报错

正文

在适配iOS13的过程中,UITextField输入中文的时候三指撤销产生了 crash。

Bugly报错

NSInternalInconsistencyException
setGroupIdentifier:: _NSUndoStack 0x1206532f0 is in invalid state, calling setGroupIdentifier with no begin group mark

堆栈信息

 CoreFoundation	___exceptionPreprocess + 220
 libobjc.A.dylib	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
 libdyld.dylib	_start + 4

问题定位

没有太多思路的时候,通过注释代码,最终定位到了问题所在。

[self addTarget:observer
         action:@selector(textChange:)
forControlEvents:UIControlEventEditinGChanged];
- (void)textChange:(UITextField *)textField {
    ... ... 
    UITextRange *selectedRange = [textField markedTextRange];
    if (!selectedRange || !selectedRange.start) {
        if (destText.length > maxLength) {
            textField.text = [destText substringToIndex:maxLength];
        }
    }
}

这段代码在输入的时候会限制文案的长度。三指撤销会触发UIControlEventEditingChanged事件,执行textChange,此时获取到的markedTextRangenil,即便是存在markedText。这就导致UITextFieldtext有可能会被修改。修改文案后再继续执行撤销操作,必定会产生 crash。

解决方案

将文案判长和截取异步添加到主队列,在下一个runloop执行。

- (void)textChange:(UITextField *)textField {
    dispatch_async(dispatch_get_main_queue(), ^{
        ... ...
    });
}

数字截断后 crash

数字输入限制长度后,超过长度后继续输入,这个时候撤销也会产生crash,而且上面的方法不可行。目前想到的方案是在UITextField的回调方法进行输入的拦截。

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
    /// 输入数字后截取字符串仍旧可以触发撤销操作导致crash, 在这里拦截一下
    if (textField.keyboardType == UIKeyboardTypeNumberPad
        && range.location >= textField.tt_maxLength) {
            return NO;
    }
    return YES;
}

以上就是iOS13适配三指撤销和文案限长实例详解的详细内容,更多关于iOS13适配三指撤销文案限长的资料请关注编程网其它相关文章!

--结束END--

本文标题: iOS13适配三指撤销和文案限长实例详解

本文链接: https://lsjlt.com/news/178617.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作