關於UITextField切換系統鍵盤和InputView的卡頓的問題

xy95778748發表於2016-07-31

想到很多讀者都是來找解決方法的,所以我先把解決方法寫出來:

原寫法:
<span style="white-space:pre">	</span>[self.textInputTextField resignFirstResponder];
        
        self.textInputTextField.inputView = inputView;
        
        [self.textInputTextField becomeFirstResponder];
解決辦法:
<span style="white-space:pre">	</span>self.textInputTextField.inputView = inputView;
        
        [self.textInputTextField reloadInputViews];
結論:
reloadInputViews去替代resignFirstResponder和becomeFirstResponder兩個方法的組合,可以解決切換系統和自定義鍵盤時產生的卡頓

但是為什麼用resignFirstResponder和becomeFirstResponder會卡頓,不懂底層,所以想不到該怎麼解釋,如果讀者有人知道,還請留下您的看法啊!!

--------------------------------------------------------------開始詳細的BB叨-------------------------------------------------------------------------

   接手外包公司做的第一版專案,IM部分用的10s迴圈訪問伺服器獲取最新訊息.看的我和經理感覺後背發涼.又因為公司其他專案也用到IM,所以我們打算自己寫一個(功能很簡單的IM).
我們IM的介面和邏輯大致參考微信去做,當然比微信的功能少很多,只是滿足簡單的交流需求.
表情鍵盤和語音訊息、圖片和發小視訊這些功能是必不可少的,所以在介面中就需要切換鍵盤,那麼,下面問題就來了

我的實現思路大概就是先"辭去當前TextField的第一響應者"->設定TextField的inputView->"當前TextField成為第一響應者"來展現自定義的View,然後再點選按鈕的時候判斷按鈕的selected狀態,"辭去當前TextField的第一響應者"->設定TextField的inputView = nil->"當前TextField成為第一響應者"來切換回系統鍵盤.程式碼如下
 if (sender.selected == NO) {
        
        [self.textInputTextField resignFirstResponder];
        
        self.textInputTextField.inputView = inputView;
        
        [self.textInputTextField becomeFirstResponder];
        
        sender.selected = YES;
        
    }else{
     
<pre name="code" class="objc">        [self.textInputTextField resignFirstResponder];
        
        self.textInputTextField.inputView = nil;
        
        [self.textInputTextField becomeFirstResponder];
sender.selected = NO; }

然後在真機上執行,忽然發現卡爆了,大概有0.5秒的卡頓...短短几行簡單無比的程式碼能卡頓這麼久,不能忍...於是乎找到底卡頓是哪句程式碼產生的,於是想到用"CACurrentMediaTime()",程式碼如下
<span style="white-space:pre">	</span>NSTimeInterval start = CACurrentMediaTime();
        
        [self.textInputTextField resignFirstResponder];
        
        NSLog(@"%f",CACurrentMediaTime() - start);
        
        start = CACurrentMediaTime();
        
        self.textInputTextField.inputView = inputView;
        
        NSLog(@"%f",CACurrentMediaTime() - start);
        
        start = CACurrentMediaTime();

        
        [self.textInputTextField becomeFirstResponder];
        
        NSLog(@"%f",CACurrentMediaTime() - start);
        
        sender.selected = YES;
        發現耗時最多的就是resignFirstResponder和becomeFirstResponder兩個方法,但是從列印時間間隔來看,程式啟動第一次撥出自定義鍵盤的時候,整個方法執行下來大概是0.5秒左右,可以理解,畢竟需要初始化view,後續再呼叫這個方法,整體時間間隔大概就是0.2秒左右.但是卡頓給我的感覺大概得有0.5秒左右.
   然後在網上搜"inputView切換卡頓",發現好像沒人遇到這個問題啊,難道我人品爆炸了?
   無意中發現一位網友用了reloadInputViews這個方法,懷著嘗試的心態試一下,我靠,好多了,很開心.但是具體的為什麼會那麼卡,不懂底層,找不到實質性原因,如有大神看到該貼,還請指教.

相關文章