问题:
使用第三方库IQKeyboardManager
时会使整个页面上移,导航栏页偏移出了显示范围。在聊天界面就会使得上面的消息看不到。
解决方法:
首先说明:在聊天界面使用IQKeyboardManager
这个第三方库无法解决这个问题,至少我没找到解决办法。网上说的那些用xib
创建UI
,把控制器的view
改成scrollview
,或纯代码创建UI
,重写loadView
方法,然后把self.view = scrollview
的解决方法会把布局搞乱。没有试,太麻烦。
解决思路:在聊天页面禁用IQKeyboardManager
,监控键盘弹出通知,自己写输入框随键盘的上移下移,自己动手丰衣足食。在网上看到一个解决思路非常不错:键盘弹出时把消息列表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];
}
我是用的xib
拖的控件自动布局,不知道为什么,在键盘通知方法里的动画block
里必须同时设置tableView.frame
和改变tableView
自动布局的constraint
,tableView
的高度才能正确跟随键盘的弹出收起而正确改变高度。如有人知道求解惑。
更新
** 注意:**
本文介绍的聊天界面的上的tableView
和输入框textfield
都是添加在ViewController
上的,VC
不是继承自UITableViewController
,这时可以把IQKeyboardManager
关掉,自己计算偏移。
但是,如果你的VC
是继承自UITableViewController
,这时你把IQKeyboardManager
关掉,当键盘遮挡textfield
的时候tableView
还是会自动偏移,因为在iOS4之后,处理键盘弹出和消失的代码已经封装在UITableViewController
里了。