聊天介面使用IQKeyboardManager導覽列及整個頁面上移的解決方案,iqkeyboard導覽列上移
問題:
使用第三方庫IQKeyboardManager時會使整個頁面上移,導覽列頁位移出了顯示範圍。在聊天介面就會使得上面的訊息看不到。
解決方案:
首先說明:在聊天介面使用IQKeyboardManager這個第三方庫無法解決這個問題,至少我沒找到解決辦法。網上說的那些用ib建立UI,把控制器的view改成scrollview,或純程式碼建立UI,重寫loadView方法,然後把self.view = scrollview的解決方案會把布局搞亂。沒有試,太麻煩。
解決思路:在聊天頁面禁用IQKeyBoard,監控鍵盤彈出通知,自己寫輸入框隨鍵盤的上移下移,自己動手豐衣足食。在網上看到一個解決思路非常不錯:鍵盤彈出時把訊息列表tableView的高度設為(螢幕高度 - 輸入框高度 - 鍵盤高度),同時輸入框上移;鍵盤消失時再把tableView的高度設為(螢幕高度 - 輸入框的高度),同時輸入框下移。這樣可以完美解決聊天列表的訊息顯示問題和鍵盤遮擋問題。
鍵盤監控代碼:
- (void)viewDidLoad { self.automaticallyAdjustsScrollViewInsets = NO; //監聽鍵盤的通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrameNotify:) name:UIKeyboardWillChangeFrameNotification object:nil];}-(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; _wasKeyboardManagerEnabled = [[IQKeyboardManager sharedManager]isEnabled]; [[IQKeyboardManager sharedManager] setEnable:NO];}-(void)viewDidDisappear:(BOOL)animated {{ [super viewWillDisappear:animated]; [[IQKeyboardManager sharedManager] setEnable:_wasKeyboardManagerEnabled];}/** * 點擊了return按鈕(鍵盤最右下角的按鈕)就會調用 */- (BOOL)textFieldShouldReturn:(UITextField *)textField{ [self sendMessage]; return YES;}/** * 當鍵盤改變了frame(位置和尺寸)的時候調用 */-(void)keyboardWillChangeFrameNotify:(NSNotification*)notify { // 0.取出鍵盤動畫的時間 CGFloat duration = [notify.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; // 1.取得鍵盤最後的frame CGRect keyboardFrame = [notify.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; // 2.計算控制器的view需要平移的距離 CGFloat transformY = keyboardFrame.origin.y - self.view.frame.size.height; // 3.執行動畫 [UIView animateWithDuration:duration animations:^{ self.myTableView.frame = CGRectMake(0, 0, SCREENW, SCREENH + transformY - self.inputView.height); self.tableViewBottomConstraint.constant = -transformY + 44;// tableView的bottom距父視圖bottom的距離 self.inputView.transform = CGAffineTransformMakeTranslation(0, transformY); [self scrollTableViewToBottom]; }];}/** * tableView快速滾動到底部 */- (void)scrollTableViewToBottom { if (self.messageFrames.count) { NSIndexPath *indexPath = [NSIndexPath indexPathForRow:(self.messageFrames.count - 1) inSection:0]; [self.myTableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; }}- (void)dealloc{ [[NSNotificationCenter defaultCenter] removeObserver:self];}