今天要做一个视图跟随键盘移动的功能,类似qq微信那种聊天输入框。之前已经做过无数次了,今天记录下实现方法和两个小坑。
以下是注册通知和通知实现方法,键盘通知百度一堆,不做赘述了。(记得移除通知)
- (void)registerNotice {
[MMNotificationCenter addObserver:self selector:@selector(showKeyboard:) name:UIKeyboardWillShowNotification object:nil];
[MMNotificationCenter addObserver:self selector:@selector(hideKeyboard:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)showKeyboard:(NSNotification *)notice {
NSLog(@"%@", notice.userInfo);
// 获取键盘的位置和大小
CGRect keyboardBounds;
[[notice.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardBounds];
NSNumber *duration = [notice.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curve = [notice.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
// Need to translate the bounds to account for rotation.
keyboardBounds = [self.view convertRect:keyboardBounds toView:nil];
// 获取输入框的位置和大小
CGRect containerFrame = self.sendView.frame;
// 计算出输入框的高度
containerFrame.origin.y = _originPointY - keyboardBounds.size.height;
// 动画改变位置
[UIView animateWithDuration:[duration doubleValue] animations:^{
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:[duration doubleValue]];
[UIView setAnimationCurve:[curve intValue]];
// 更改输入框的位置
self.sendView.frame = containerFrame;
}];
}
- (void)hideKeyboard:(NSNotification *)notice {
CGRect keyboardBounds;
[[notice.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] getValue: &keyboardBounds];
NSNumber *duration = [notice.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSNumber *curve = [notice.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey];
// Need to translate the bounds to account for rotation.
keyboardBounds = [self.view convertRect:keyboardBounds toView:nil];
// 获取输入框的位置和大小
CGRect containerFrame = self.sendView.frame;
containerFrame.origin.y = _originPointY;
// 动画改变位置
[UIView animateWithDuration:[duration doubleValue] animations:^{
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:[duration doubleValue]];
[UIView setAnimationCurve:[curve intValue]];
// 更改输入框的位置
self.sendView.frame = containerFrame;
}];
}
主要记录以下两个坑:
- 我的布局最初是使用masonry的,也就是使用了autoLayout,但是在动画效果的时候改变了frame,这样会造成一些奇奇怪怪的问题,所以之后统一使用了frame布局。(具体原因与使用autoLayout布局点这里)
UIKeyboardWillShowNotification并不只是在获取焦点的时候调用,尤其是某些三方的键盘,可能会发送多次通知,所以在处理输入框位置的时候需要注意(我使用的使全局记录)。