我们通常在项目开发中必定会遇到的一个问题就是键盘对输入框的遮挡问题,通常我们会有多种解决方案,最常被要求的产品需求就是输入框需要跟随键盘的移动而移动,如下例子:
uiTextFeild.gif这样可以满足我们大多数需求,本篇文章的案例适合所有iPhone 和 iPad设备输入框的遮挡问题。
当然很多人可能会提出第三方库 IQKeyboardManager
,这个库个人没使用过,原因是很多人说会产生一些莫名其妙的bug,所有这篇文章我就分享一下个人常用的解决方案。
通常我们需要监听键盘的弹出和收回 ,以及监听UITextextField
的代理方法,然后实现我们的需求。
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification object:nil];
从UIKeyboardWillHideNotification 和 UIKeyboardWillShowNotification 的noti.userInfo
中取出一个字典,我们可以获取到键盘的以下值:
UIKeyboardAnimationCurveUserInfoKey
UIKeyboardAnimationDurationUserInfoKey
UIKeyboardBoundsUserInfoKey
UIKeyboardCenterBeginUserInfoKey
UIKeyboardCenterEndUserInfoKey
UIKeyboardFrameBeginUserInfoKey
UIKeyboardFrameEndUserInfoKey
UIKeyboardIsLocalUserInfoKey
通过这几个key 我们可以获取到键盘的高度,可动画时间,以及动画曲线
这里我们需要关注textFeild 的代理方法:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
及当键盘开始编辑时候,我们修改self.view.frame
,核心算法
// 键盘高度
CGFloat kbHeight = [[keyboardInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
//self.view.frame 的偏移量
// INTERVAL_KEYBOARD 输入框和键盘之间的间隔,可自定义
// textField.y + textField.height
CGFloat offset = (textField.frame.origin.y + textField.frame.size.height + INTERVAL_KEYBOARD) - (self.view.frame.size.height - kbHeight);
这里需要对offset
做容错处理:
if (offset > 0) {
// 如果 INTERVAL_KEYBOARD 间隔过大,需要减少偏移量
if (offset > kbHeight) {
offset = kbHeight-50;
}
[self animationWithkeybooard:^{
self.view.frame = CGRectMake(0, -offset, self.view.frame.size.width, self.view.frame.size.height);
}];
}else{
[self animationWithkeybooard:^{
self.view.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}];
}
这里的animationWithkeybooard
是对动画的一个简单的封装
- (void)animationWithkeybooard:(void (^)(void))animations{
NSTimeInterval duration = [[keyboardInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] floatValue];
UIViewAnimationCurve curve = [[keyboardInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
[UIView setAnimationCurve:curve];
animations();
[UIView commitAnimations];
}
需要注意一点是
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
- (void)keyboardWillShow:(NSNotification *)noti;
第一个方法回调早于第二个,这就会造成self.view.frame
不能改变,首要在keyboardWillShow
动态调用一次第一个方法。
这样具体的逻辑以及全部完成了,有兴趣的可以下载一下Example自己尝试一下。
网友评论