正文
在适配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,此时获取到的markedtextrange是nil,即便是存在markedtext。这就导致uitextfield的text有可能会被修改。修改文案后再继续执行撤销操作,必定会产生 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适配三指撤销文案限长的资料请关注代码网其它相关文章!
发表评论