其实防止键盘遮挡的思路很简单,就是通过键盘的通知来获取键盘的高度,然后将view向上偏移这个高度,自然就防止了键盘将内容遮挡住。
在此我的解决方法是,将这个操作放到UIViewController的类别里,只要在任何ViewController里面添加了键盘通知,就能具有防止键盘遮挡的功能。话不多说,直接上代码。
static void * keyboardHideTapGestureKey = (void *)@"keyboardHideTapGesture";//键盘点击隐藏手势
static void * objectViewKey = (void *)@"objectView";//目标视图
#pragma mark - 设置键盘隐藏单击手势 setter getter
- (void)setKeyboardHideTapGesture:(UITapGestureRecognizer *)keyboardHideTapGesture{
objc_setAssociatedObject(self, keyboardHideTapGestureKey, keyboardHideTapGesture, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (id)getKeyboardHideTapGesture{
return objc_getAssociatedObject(self, keyboardHideTapGestureKey);
}
#pragma mark - 设置获取目标对象 setter getter
- (void)setObjectView:(UIView *)objectView{
objc_setAssociatedObject(self, objectViewKey, objectView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (id)getObjectView{
return objc_getAssociatedObject(self, objectViewKey);
}
首先定义2个变量,一个存储单击手势,一个存储响应的输入框。由于是在类别里,所以只能通过runtime设置属性。上面代码分别写了2个变量的setter和getter。
#pragma mark - 添加键盘通知
- (void)addNotification{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardNotify:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardNotify:) name:UIKeyboardWillHideNotification object:nil];
[self setKeyboardHideTapGesture:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureHandel)]];
[self.view addGestureRecognizer:[self getKeyboardHideTapGesture]];
}
这个方法来进行键盘通知的添加,以及手势的添加。
#pragma mark - 清理通知和移除手势
- (void)clearNotificationAndGesture{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self.view removeGestureRecognizer:[self getKeyboardHideTapGesture]];
}
这个方法用于在ViewController的dealloc中进行调用,移除通知和手势,让ViewController能被释放。当然不需要键盘遮挡时也能使用-.-。
#pragma mark - 单击手势调用
- (void)tapGestureHandel{
[[UIApplication sharedApplication].keyWindow endEditing:YES];
}
这个方法是响应单击手势,作用是结束编辑状态,收起键盘。
重头戏来了:
#pragma mark - 键盘通知接收处理
- (void)keyboardNotify:(NSNotification *)notify{
NSValue * frameNum = [notify.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
CGRect rect = frameNum.CGRectValue;
CGFloat keyboardHeight = rect.size.height;//键盘高度
CGFloat duration = [[notify.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];//获取键盘动画持续时间
NSInteger curve = [[notify.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];//获取动画曲线
if ([notify.name isEqualToString:UIKeyboardWillShowNotification]) {//键盘显示
[self findFirstResponse:self.view];
UIView * tempView = [self getObjectView];
CGPoint point = [tempView convertPoint:CGPointMake(0, 0) toView:[UIApplication sharedApplication].keyWindow];//计算响应者到和屏幕的绝对位置
CGFloat keyboardY = APPWINDOWHEIGHT - keyboardHeight;//键盘的y值
CGFloat tempHeight = point.y + tempView.frame.size.height;//输入框的顶部坐标加上输入框的高度
if (tempHeight > keyboardY) {//判断输入框是否被键盘遮住
CGFloat offsetY;
if (APPWINDOWHEIGHT-tempHeight < 0) {//判断是否超出了屏幕,超出屏幕做偏移纠正
offsetY = keyboardY - tempHeight + (tempHeight-APPWINDOWHEIGHT);
}else{
offsetY = keyboardY - tempHeight;
}
if (duration > 0) {
[UIView animateWithDuration:duration delay:0 options:curve animations:^{
self.view.transform = CGAffineTransformMakeTranslation(0, offsetY);
} completion:^(BOOL finished) {
}];
}else{
self.view.transform = CGAffineTransformMakeTranslation(0, offsetY);
}
}
}else if ([notify.name isEqualToString:UIKeyboardWillHideNotification]){//键盘隐藏
if (duration > 0) {
[UIView animateWithDuration:duration delay:0 options:curve animations:^{
self.view.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
}];
}else{
self.view.transform = CGAffineTransformIdentity;
}
}
}
#pragma mark - 查找第一响应者
//通过递归判获取响应者的视图
- (void)findFirstResponse:(UIView *)view{
UIView * ojView = [self getObjectView];
ojView = nil;
for (UIView * tempView in view.subviews) {
if ([tempView isFirstResponder] &&
([tempView isKindOfClass:[UITextField class]] ||
[tempView isKindOfClass:[UITextView class]])) {//要进行类型判断
[self setObjectView:tempView];
}
if (tempView.subviews.count != 0) {
[self findFirstResponse:tempView];
}
}
}
项目在这里-->下载
如果觉得好用欢迎star。