iOS 键盘挡住视图优化

前言:虽然说目前也没多少APP输入框会被弹出的键盘遮住,但是遇到了也挺麻烦的,所以,我也简单的整理了一下,代码如下:


1574840914802133.gif

添加监听

#pragma mark - 键盘事件
- (void)initKeyboardObserver
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillShow:)
                                                 name:UIKeyboardWillShowNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardDidShow:)
                                                 name:UIKeyboardDidShowNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardWillHide:)
                                                 name:UIKeyboardWillHideNotification
                                               object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(keyboardDidHide:)
                                                 name:UIKeyboardDidHideNotification
                                               object:nil];
}

参数描述

#define MAINSCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
#define MAINSCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
#define FIRSTRESPONDERBOTTOM 20

//是否正在显示键盘
@property (nonatomic, assign) BOOL isKeyboardShow;
//是否第三方
@property (nonatomic, assign) BOOL isThirdPartKeyboard;
//次数
@property (nonatomic, assign) NSInteger keyboardShowTime;
//键盘动画时间
@property (nonatomic, assign) CGFloat keyboardAnimateDur;
//键盘位置
@property (nonatomic, assign) CGRect keyboardFrame;
//改变的高度
@property (nonatomic, assign) CGFloat changeHeight;

@property (nonatomic, assign) CGFloat oldY;

监听处理

//键盘即将显示
- (void)keyboardWillShow:(NSNotification*)notification
{
    
    NSValue* keyboardBoundsValue = [[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey];
    CGRect keyboardRect = [keyboardBoundsValue CGRectValue];
    
    NSNumber* keyboardAnimationDur = [[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    float animationDur = [keyboardAnimationDur floatValue];
    
    _keyboardShowTime++;
    //第三方输入法有bug第一次弹出没有keyboardRect
    if (animationDur > 0.0f && keyboardRect.size.height == 0) {
        _isThirdPartKeyboard = YES;
    }
    //第三方输入法有动画间隔时没有高度
    if (_isThirdPartKeyboard) {
        // 第三次调用keyboardWillShow的时候键盘完全展开
        if (_keyboardShowTime == 3 && keyboardRect.size.height != 0 && keyboardRect.origin.y != 0) {
            _keyboardFrame = keyboardRect;
            [self changeForKeyBoradFrame:keyboardRect];
        }
        if (animationDur > 0.0) {
            _keyboardAnimateDur = animationDur;
        }
    } else {
        if (animationDur > 0.0) {
            _keyboardFrame = keyboardRect;
            _keyboardAnimateDur = animationDur;
            [self changeForKeyBoradFrame:keyboardRect];
        }
    }
}

//键盘已经显示
- (void)keyboardDidShow:(NSNotification*)notification {
    _isKeyboardShow = YES;
}
//键盘即将隐藏
- (void)keyboardWillHide:(NSNotification*)notification
{
    NSNumber* keyboardAnimationDur = [[notification userInfo] objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    float animationDur = [keyboardAnimationDur floatValue];
    
    _isThirdPartKeyboard = NO;
    _keyboardShowTime = 0;
    
    if (animationDur > 0.0 && self.changeHeight<0) {
        CGRect animationFrame = self.animationView.frame;
        animationFrame.origin.y -= self.changeHeight;
        [UIView animateWithDuration:_keyboardAnimateDur animations:^{
            self.animationView.frame = animationFrame;
            [self.animationView layoutIfNeeded];
            [self.animationView layoutSubviews];
        } completion:^(BOOL finished) {
            self.changeHeight = 0;
            self.firstResponderInWindowFrame = CGRectZero;
            self.keyboardFrame = CGRectZero;
        }];
    }
}
//键盘已经隐藏
- (void)keyboardDidHide:(NSNotification*)notification {
    _isKeyboardShow = NO;
}

- (void)changeForKeyBoradFrame:(CGRect)keyboardRect {
    //判断键盘是不是低于第一响应者+预设的空隙
    //计算:键盘的Y - 第一响应者的Y+高+离键盘的空隙 =需要移动的高度
    CGFloat deviation = keyboardRect.origin.y - (self.firstResponderInWindowFrame.origin.y +self.firstResponderInWindowFrame.size.height +FIRSTRESPONDERBOTTOM);
    if (deviation <0) {
        self.changeHeight = deviation;
        CGRect animatieViewFrame = self.animationView.frame;
        //防止多次计算导致位置错误
        if (self.oldY ==0) {
            self.oldY = animatieViewFrame.origin.y;
        }
        animatieViewFrame.origin.y =self.oldY+deviation;
        
        [UIView animateWithDuration:_keyboardAnimateDur animations:^{
            self.animationView.frame = animatieViewFrame;
            
            [self.animationView layoutIfNeeded];
            [self.animationView layoutSubviews];
        }completion:^(BOOL finished) {
            
        }];
    }
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

最后,调用我感觉也算简单了
需要传2个参数 一个是animationView,初始化的时候就可以传,另一个是firstResponder点击的视图,在点击的时候传,类似下面这样。

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    [HYKeyboardManager sharedManager].firstResponder =textField;
    return YES;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 小星先秦:佚名嘒彼小星,三五在东。肃肃宵征,夙夜在公。寔命不同。嘒彼小星,维参与昴。肃肃宵征,抱衾与裯。寔命不犹。...
    To者也阅读 1,138评论 0 1
  • 价值人数频次=品牌要高频次和小惊喜,不要憋大招,个人品牌是这样,产品思维也是这样,做出最小化产品,快速迭代打造个人...
    生活建筑师阅读 141评论 0 2
  • 我害怕比较,一比较就有高低,一比较就会有差距,一比较就会有失落,太多不开心源于比较,为什么想要跟别人比呢,因为欲望...
    YM0202阅读 233评论 0 0