iOS13适配三指撤销和文案限长实例详解
<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>正文</li><ul class="second_class_ul"><li>Bugly报错</li><li>堆栈信息</li><li>问题定位</li><li>解决方案</li></ul><li>数字截断后 crash</li><ul class="second_class_ul"></ul></ul></div><p class="maodian"></p><h2>正文</h2><p>在适配iOS13的过程中,<code>UITextField</code>输入中文的时候三指撤销产生了 crash。</p>
<p class="maodian"></p><h3>Bugly报错</h3>
<div class="jb51code"><pre class="brush:bash;">NSInternalInconsistencyException
setGroupIdentifier:: _NSUndoStack 0x1206532f0 is in invalid state, calling setGroupIdentifier with no begin group mark
</pre></div>
<p class="maodian"></p><h3>堆栈信息</h3>
<div class="jb51code"><pre class="brush:cpp;"> CoreFoundation ___exceptionPreprocess + 220
libobjc.A.dylib objc_exception_throw + 56
Foundation -
Foundation - + 240
UIKitCore - + 72
UIKitCore - + 96
UIKitCore - + 152
UIKitCore - + 96
xxxxx - + 288
UIKitCore - + 240
UIKitCore - + 408
UIKitCore - + 520
UIKitCore - + 2324
UIKitCore - + 3352
UIKitCore - + 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
</pre></div>
<p class="maodian"></p><h3>问题定位</h3>
<p>没有太多思路的时候,通过注释代码,最终定位到了问题所在。</p>
<div class="jb51code"><pre class="brush:cpp;">[self addTarget:observer
action:@selector(textChange:)
forControlEvents:UIControlEventEditingChanged];
</pre></div>
<div class="jb51code"><pre class="brush:cpp;">- (void)textChange:(UITextField *)textField {
... ...
UITextRange *selectedRange = ;
if (!selectedRange || !selectedRange.start) {
if (destText.length > maxLength) {
textField.text = ;
}
}
}
</pre></div>
<p>这段代码在输入的时候会限制文案的长度。三指撤销会触发<code>UIControlEventEditingChanged</code>事件,执行<code>textChange</code>,此时获取到的<code>markedTextRange</code>是<code>nil</code>,即便是存在<code>markedText</code>。这就导致<code>UITextField</code>的<code>text</code>有可能会被修改。修改文案后再继续执行撤销操作,必定会产生 crash。</p>
<p class="maodian"></p><h3>解决方案</h3>
<p>将文案判长和截取异步添加到主队列,在下一个<code>runloop</code>执行。</p>
<div class="jb51code"><pre class="brush:cpp;">- (void)textChange:(UITextField *)textField {
dispatch_async(dispatch_get_main_queue(), ^{
... ...
});
}
</pre></div>
<p class="maodian"></p><h2>数字截断后 crash</h2>
<p>数字输入限制长度后,超过长度后继续输入,这个时候撤销也会产生crash,而且上面的方法不可行。目前想到的方案是在<code>UITextField</code>的回调方法进行输入的拦截。</p>
<div class="jb51code"><pre class="brush:cpp;">- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
/// 输入数字后截取字符串仍旧可以触发撤销操作导致crash, 在这里拦截一下
if (textField.keyboardType == UIKeyboardTypeNumberPad
&& range.location >= textField.tt_maxLength) {
return NO;
}
return YES;
}</pre></div>
<p>以上就是iOS13适配三指撤销和文案限长实例详解的详细内容,更多关于iOS13适配三指撤销文案限长的资料请关注琼殿技术社区其它相关文章!</p>
<div class="art_xg">
<b>您可能感兴趣的文章:</b><ul><li>IOS开发自定义Button的外观和交互行为示例详解</li><li>IOS开发Objective-C Runtime使用示例详解</li><li>iOS数据持久化UserDefaults封装器使用详解</li><li>iOS数据持久化KeyChain数据操作详解</li><li>iOS 16 CocoaAsyncSocket 崩溃修复详解</li><li>iOS开发蓝牙技术应用增加无线连接功能</li></ul>
</div>
</div>
<!--endmain-->
頁:
[1]