iOS 14 開始,系統(tǒng)的 emoji 鍵盤內(nèi)部有一個(gè)搜索框 TUIEmojiSearchTextField

? ? 這個(gè)搜索框如果在 init 的時(shí)候設(shè)置 delegate(或者設(shè)置了keyboardAppearance) 會(huì)導(dǎo)致觸發(fā)死循環(huán),目前我們并不需要為這個(gè)新的系統(tǒng)TF做代理,所以需要過濾掉它。
? ? ?我出錯(cuò)的位置是BlocksKit里面改用了“TUIEmojiSearchTextField”的delegate。BlocksKit會(huì)在把delegate變成block使用,非常方便,但是這里明顯是轉(zhuǎn)換了一個(gè)我們并不需要的delegate所以在BlocksKit獲取delegate的地方過濾它。
? ? ?通過斷點(diǎn),我發(fā)現(xiàn)會(huì)有一個(gè)TUIEmojiSearchTextField的delegate在“bk_registerDynamicDelegateNamed:forProtocol:”方法中被調(diào)用,它主要功能就是修改 getter 和 setter 方法,將原有的?delegate?轉(zhuǎn)發(fā)到?realDelegate,修改原有的?delegate?的實(shí)現(xiàn)。下圖即是bk_registerDynamicDelegateNamed:forProtocol方法。

在setdelegate中,過濾掉TUIEmojiSearchTextField,加入如下代碼
?if(@available(iOS13.0, *)) {? ? ? ? ? ??if([delegateisKindOfClass:NSClassFromString(@"TUIEmojiSearchTextField")]) {? ? ? ? ? ? ? ? delegate =nil;
? ? ? ? ???}
? ? ? ??}
變成下面
IMPsetterImplementation =imp_implementationWithBlock(^(NSObject*delegatingObject,iddelegate) {
A2DynamicDelegate*dynamicDelegate =getDynamicDelegate(delegatingObject, protocol, infoAsPtr,YES);
if([delegateisEqual:dynamicDelegate]) {
delegate =nil;
}
? ? ? ? if(@available(iOS13.0, *)) {
? ? ? ? ? ? if([delegateisKindOfClass:NSClassFromString(@"TUIEmojiSearchTextField")]) {
? ? ? ? ? ? ? ? delegate =nil;
? ? ? ? ? ? }
? ? ? ? }
dynamicDelegate.realDelegate= delegate;
});
即可。
文章方法參考自騰訊的QMUI的1042問題:Tencent/QMUI_iOS/issues/1042