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