9.27更新:
新项目中重新对键盘弹出的效果进行了封装,只需要三步就可以完成相关操作,并且支持TextView了。
Git地址,如果好用请给个star,非常感谢!
添加观察者
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addKeyboardNotification];
}
隐藏键盘操作
[[self.view getIsEditingText] resignFirstResponder];
移除观察者
- (void)dealloc {
[self.view removeKeyboardNotification];
}
正文:
之前项目中遇到键盘弹出遮挡输入框时, 都是使用三方库DaiDodgeKeyboard
进行界面上移动画, 这个三方库很方便, 但是有时候会出现如tableview.tableFooterView
变短、大屏适配失效等非常诡异的情况, 所以本狼参考着网上资料自己动手实现了一个简单的效果.
- 添加一下键盘的通知, 并记得移除
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- 写一个方法取到编辑状态下的
textfield
- (void)getIsEditingView:(UIView *)rootView {
for (UIView *subView in rootView.subviews) {
if ([subView isKindOfClass:[UITextField class]]) {
if (((UITextField *)subView).isEditing) {
self.editingTextField = subView;
return;
}
}
[self getIsEditingView:subView];
}
}
- 计算已经拿到的
textfield
在屏幕中的位置
- (CGFloat)screenViewYValue:(UIView *)textfield {
CGFloat y = 0;
for (UIView *view = textfield; view; view = view.superview) {
y += view.frame.origin.y;
if ([view isKindOfClass:[UIScrollView class]]) {
// 如果父视图是UIScrollView则要去掉内容滚动的距离
UIScrollView* scrollView = (UIScrollView*)view;
y -= scrollView.contentOffset.y;
}
}
return y;
}
因为我们不可能凡是textfield
就上移, 所以要拿到位置再进行判断.
- 最后针对拿到的这个位置来进行视图上移处理, 也就是通知执行的方法
- (void)keyboardWillShow:(NSNotification *)noti {
// 拿到正在编辑中的textfield
[self getIsEditingView:self.view];
// textfield的位置
CGFloat viewY = [self screenViewYValue:self.editingTextField];
// 键盘的Y值
NSDictionary *userInfo = [noti userInfo];
NSValue *value = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGFloat keyboardEndY = value.CGRectValue.origin.y;
// 动画
NSNumber *duration = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
[UIView animateWithDuration:duration.doubleValue animations:^{
if (viewY+30 > keyboardEndY) {
CGRect rect = self.tableView.frame;
rect.origin.y += keyboardEndY - (viewY+30);
self.tableView.frame = rect;
}
}];
}
- 键盘收起方法就比较简单了, 直接复位即可
- (void)keyboardWillHide:(NSNotification *)noti {
CGRect rect = self.tableView.frame;
rect.origin.y = 0;
self.tableView.frame = rect;
}
至此就基本实现了键盘弹出的动画效果, 可能还要具体需求具体分析, 不过一般场景已经够用, 其中-(CGFloat)screenViewYValue:
方法是一个系列的, 本狼是写在UIView
的类别里, 这里为了方便展示就单独拿了出来, 建议还是将方法整理写到类别中.