开发者

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

开发者 https://www.devze.com 2023-01-30 10:20 出处:网络 作者: yuec
目录正文Bugly报错堆栈信息问题定位解决方案数字截断后 crash正文 在适配IOS13的过程中,UITextField输入中文的时候三指撤销产js生了 crash。
目录
  • 正文
    • Bugly报错
    • 堆栈信息
    • 问题定位
    • 解决方案
  • 数字截断后 crash

    正文

    在适配IOS13的过程中,UITextField输入中文的时候三指撤销产js生了 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
     U编程客栈IKitCore	-[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	__开发者_Python培训_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的回调方法进行输入的nYhfsel拦截。

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

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

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消