开发时页面中会有很多输入框,不可避免的会有键盘弹出时挡住输入框的情况(还有iPhone尺寸,键盘的高度不一致等原因)。
一般做法是监听键盘弹出和隐藏的通知,弹出时让view上移一部分(键盘的高度),隐藏时view下移一部分。
还有做法就是在textField的代理方法中上移view和下移view,在- (void)textFieldDidBeginEditing:(UITextField *)textField中上移view,在- (void)textFieldDidEndEditing:(UITextField *)textField中下移view。
但是,这两种做法都不能完美解决我们标题的问题。
我的做法是将上面两种方法结合,通过通知获得键盘的高度,通过textField的代理方法我们能知道是哪一个textField,然后将这个textField的frame转化到控制器的view的frame,这样我们就可以比较适否被遮挡,遮挡的话进行上移等等。
解决方法:创建一个控制器,作为其他控制器的基类,这样其他控制器中的输入框只要设置了delegate是self就不用写多余代码。
#import "YTUIViewController.h"
#import "Define.h"
@interface YTUIViewController ()
{
CGFloat viewBottom; //textField的底部
CGFloat keyboardDuration; //键盘隐藏需要的时间 = 键盘弹出的时间
}
@end
@implementation YTUIViewController
//移除监听
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self setupForKeyBoard];
}
#pragma mark -键盘相关
//键盘的准备
- (void)setupForKeyBoard
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
//点击手势点击非输入框区域隐藏键盘
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(keyBoardHideAction)];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
//键盘显示后添加手势
[nc addObserverForName:UIKeyboardWillShowNotification object:nil queue:mainQueue usingBlock:^(NSNotification * _Nonnull note) {
[self.view addGestureRecognizer:tap];
[self keyboardWillShow:note];
}];
//键盘消失后移除手势
[nc addObserverForName:UIKeyboardWillHideNotification object:nil queue:mainQueue usingBlock:^(NSNotification * _Nonnull note) {
[self.view removeGestureRecognizer:tap];
//键盘动画时间
double duration = [[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration animations:^{
self.view.frame = CGRectMake(, , SCREEN_WIDTH, SCREEN_HEIGHT);
}];
}];
}
//键盘消失后view下移
- (void)keyBoardHideAction
{
NSLog(@"begin hide");
[self.view endEditing:YES];
}
//通过note获取键盘高度,键盘动画时间
- (void)keyboardWillShow:(NSNotification *)note
{
NSLog(@"后调用");
//键盘高度
CGFloat keyboardH = [[note.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
//键盘动画时间
keyboardDuration = [[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
if (viewBottom + keyboardH < SCREEN_HEIGHT) {
return;
}
else
{
[UIView animateWithDuration:keyboardDuration animations:^{
self.view.frame = CGRectMake(, - ( keyboardH - (SCREEN_HEIGHT - viewBottom)), SCREEN_WIDTH, SCREEN_HEIGHT);
}];
}
}
#pragma mark -UITextFieldDelegate
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
NSLog(@"最先调用");
//将textField的rect转换到self.view上
CGRect rect = [textField.superview convertRect:textField.frame toView:self.view];
//textField的底部
viewBottom = rect.origin.y + rect.size.height;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
NSLog(@"最后调用");
[UIView animateWithDuration:keyboardDuration animations:^{
self.view.frame = CGRectMake(, , SCREEN_WIDTH, SCREEN_HEIGHT);
}];
}
注意:.h文件如下,遵循协议申明在.h文件,这样子类不用再申明遵循该协议
#import <UIKit/UIKit.h>
@interface YTUIViewController : UIViewController<UITextFieldDelegate>
@end
附上demo地址:[KeyboardDemo](https://git.oschina.net/yant/KeyboardDemo)
如有不对,请指正。