在开发APP过程中,不免会遇到页面需要多个 UITextField 的需求,那么问题来了:当输入框过多时,弹起键盘会遮盖住输入框,或者需要依次点击输入框才能输入。用户的输入体验非常差。为解决这个问题,我们让输入框跟随键盘自动调整高度,并且点击回车键自动跳转到下一个输入框进行输入。
具体效果如图:
需求分析:
简单分析一下:
- 点击输入框时,输入框随着键盘弹起,自动调整高度,使输入框位于键盘上方。
- 点击回车,自动切换到下一个输入框进行输入,同时调整输入框高度。
为了使输入框能够上下滑动,这里将所有 UITextField 放在一个 scrollview 上,然后添加键盘监听事件,当用户点击输入框时,触发键盘弹起,此时调整scrollView 的 contentOffset,使输入框正好位于键盘上方。
添加键盘监听:
1
2
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
键盘响应事件:
1
2
3
4
5
6
7
- (void)keyboardWillShow:(NSNotification *)notification {
//获取键盘高度,在不同设备上,以及中英文下是不同的
CGFloat kbHeight = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
_keyBoardHeight = kbHeight;
[self boardAutoAdjust:kbHeight];
}
1
2
3
4
5
- (void)keyboardWillHide:(NSNotification *)notify {
// 键盘动画时间
_keyBoardHeight = 0;
[self.board setContentOffset:CGPointMake(0,-64) animated:YES];
}
UITextField 代理事件:
1
2
3
4
5
6
7
8
9
10
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
NSLog(@"=== %@", [NSValue valueWithCGRect:textField.frame]);
self.fistField = textField;
if (_keyBoardHeight > 0) {
[self boardAutoAdjust:_keyBoardHeight];
}
return YES;
}
scrollview 偏移量计算
scrollView 需要偏移的量 =页面总高度
- 输入框高度
- 键盘高度
,当输入框高于键盘时,偏移量小于零,反之,偏移量大于零。
偏移量计算方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- (void)boardAutoAdjust:(CGFloat)keyboardHeight {
if (self.fistField) {
CGRect rec = _fistField.frame;
CGFloat max_y = CGRectGetMaxY(rec);
CGFloat b_offset = self.view.height - max_y - keyboardHeight;
CGPoint point = self.board.contentOffset;
point.y = -b_offset;
[self.board setContentOffset:point animated:YES];
}
}
键盘回车事件
当点击键盘回车时,自动跳转到下一个输入框进行输入,最后一个输入框点击回车时,收起键盘,整体回到原先的布局高度。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if (textField.returnKeyType == UIReturnKeyNext) {
[textField resignFirstResponder];
UITextField *next = [self.textfields objectAtIndex:(textField.tag + 1)];
[next becomeFirstResponder];
} else if (textField.returnKeyType == UIReturnKeyDone) {
[textField resignFirstResponder];
}
return YES;;
}