iOS防止键盘遮挡

作者: CxDtreeg | 来源:发表于2016-01-06 23:52 被阅读721次

其实防止键盘遮挡的思路很简单,就是通过键盘的通知来获取键盘的高度,然后将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。

相关文章

网友评论

本文标题:iOS防止键盘遮挡

本文链接:https://www.haomeiwen.com/subject/prhfkttx.html