键盘弹出和隐藏的三种方式

1.在keyboardWillShow和keyboardWillHide方法中做键盘处理

// 监听键盘通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

#pragma mark - 键盘处理
- (void)keyboardWillShow:(NSNotification *)note {
    // 取出键盘最终的frame
    CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    // 取出键盘弹出需要花费的时间
    double duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    // 修改约束
    self.bottomSpacing.constant = rect.size.height;
    [UIView animateWithDuration:duration animations:^{
        [self.view layoutIfNeeded];
    }];
}

- (void)keyboardWillHide:(NSNotification *)note {
    // 取出键盘弹出需要花费的时间
    double duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    // 修改约束
    self.bottomSpacing.constant = 0;
    [UIView animateWithDuration:duration animations:^{
        [self.view layoutIfNeeded];
    }];
}

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

2.在keyboardWillChangeFrame方法中做键盘处理

// 监听键盘通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];

#pragma mark - 键盘处理
- (void)keyboardWillChangeFrame:(NSNotification *)note {
    // 取出键盘最终的frame
    CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    // 取出键盘弹出需要花费的时间
    double duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    
    // 修改约束
    self.bottomSpacing.constant = [UIScreen mainScreen].bounds.size.height - rect.origin.y;
    [UIView animateWithDuration:duration animations:^{
        [self.view layoutIfNeeded];
    }];
}

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

3.通过tranform做键盘处理

// 监听键盘通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];

#pragma mark - 键盘处理
- (void)keyboardWillChangeFrame:(NSNotification *)note {
 // 取出键盘最终的frame
    CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    // 取出键盘弹出需要花费的时间
    double duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    // 修改transform
    [UIView animateWithDuration:duration animations:^{
        CGFloat ty = [UIScreen mainScreen].bounds.size.height - rect.origin.y;
        self.view.transform = CGAffineTransformMakeTranslation(0, - ty);
    }];

}

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

4.关于layoutIfNeeded

对于layoutIfNeeded本人浅谈下自己的理解,首先我们要了解为何在用到用到constraint的动画时以下代码无法实现动画的功能:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    
    [UIView animateWithDuration:2.0 animations:^{
      
       self.blueViewH.constant = 80;
    }];
}

而我们直接使用frame的时候动画是可以实现的:

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    
    [UIView animateWithDuration:2.0 animations:^{
        
        CGRect  size =self.blueView.frame;
        
        size.size.height = 80;
        
        self.blueView.frame = size;
        
    }];
}

说明,我们所调用的方法是正确的,那么我们可以大胆的假设"self.blueViewH.constant = 80;"在这句赋值并没有在该方法中完成,从而导致动画并没有实现;而要进行Constraint动画则需要对NSLayoutConstraint的对象赋值之后调用layoutIfNeeded方法才能实现动画(由于Xcode改版后调用layoutIfNeeded方法只会刷新子控件键,因此要使用必须通过它的父类):

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    
    self.blueViewW.constant = 80;
    
    [UIView animateWithDuration:2.0 animations:^{
  
        [self.view layoutIfNeeded];
    }];
}

通过两个能够实现动画的代码比较,我们就可以推测出NSLayoutConstraint的本质就是在系统底层转换为frame,并且NSLayoutConstraint的转换还不是在你赋值的时候就转换完成,而是极可能在某一方法结束后才进行转换;因此我们调用layoutIfNeeded方法对"self.blueViewW.constant = 80;"代码进行强制刷新的时候便能实现该动画了.

总之,layoutIfNeeded在需要重新布局的时候立即刷新进行重新布局,不受其他因素影响.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,259评论 4 61
  • 20/02/2017 一件事情的伟大,必定是一群人的伟大! 那么对于团队的管理和有效合作怎么样去进行呢?——最有效...
    氢哈哈阅读 770评论 4 3
  • 方案一: 重新修改密码。 方案一: 重启电脑。 方案三:设置账户信息:
    SamCheck阅读 1,760评论 0 1
  • 我不喜欢下雨,因为偶尔叫不到车,总会被急匆匆的车甩了一身的泥点子。这是我偶尔的心境,焦躁,不耐烦,活不到当下。我总...
    素言简说阅读 326评论 3 4
  • 嘻嘻嘻嘻嘻全世界心态最不健康的人,在搬完家后,就可以考虑死一死了。 我大概真的油盐不进吧,我最信任最亲近的那个人说...
    趁早退场阅读 151评论 0 1