iOS 聊天输入框跟随键盘运动动画实现

在上家公司做项目的时候,布局使用的是Masonry,常用的位置变换动画就是约束动画啦,也就是更新某一控件的约束之后在UIView 的animationWithDuration:animations:方法中调用该控件的layoutIfNeeded方法。
诚然这种动效是线性的,不会有淡入淡出等效果。

约束动画这种形式一般情况下还是没什么问题的,如果项目经理没啥特殊要求的话。

于是乎,我就在IM功能输入文本弹出键盘时也用了这种动画,因为当时就觉得,控件我是用约束布局的,弹出键盘时去设置它的frame应该不好吧。带着这种心态就没去多想,还一直疑惑着微信QQ那种应该不是用约束实现的吧,由于上司没觉得这样有什么不好而且一直都在做功能、debug、改需求,也就一直都没管它。

恰恰因为这个昨天面试随手科技时就被面试官小哥赤裸裸的嫌弃了,Kuing~

今天上午去面试,下午玩了一下,感觉使用约束布局,再去修改frame其实也不是想象的那样会带来太多不好的影响,最主要的影响就是不能自适应高度了,而且一旦旋屏,设置的frame就失效了,还要去更新约束(可是谁家的聊天页需要旋屏又支持左右滑动切换会话呢?答案是没有别人,只有我的上家@.@)


废话了半天,下面是实现的核心代码

/**
 处理键盘弹出、隐藏、更新frame动画

 @param duration 动画时间
 @param keyboardOriginY 键盘纵向起点
 */
- (void)keybaordAnimationWithDuration:(CGFloat)duration keyboardOriginY:(CGFloat)keyboardOriginY{
    CGFloat contentHeight = _tableView.contentSize.height;

    //作为视图的键盘,弹出动画也是UIViewAnimationOptionCurveEaseIn的方式
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
        //text field
        CGPoint textFieldOrigin = _textField.frame.origin;
        CGSize  textFieldSize = _textField.frame.size;
        CGRect  textFieldAimFrame = CGRectMake(textFieldOrigin.x, keyboardOriginY - textFieldSize.height, textFieldSize.width, textFieldSize.height);
        _textField.frame = textFieldAimFrame;

        //table view
        CGPoint tableViewOrigin = _tableView.frame.origin;
        CGSize  tableViewSize   = _tableView.frame.size;
        CGRect  tableViewAimFrame = CGRectMake(tableViewOrigin.x, tableViewOrigin.y, tableViewSize.width, textFieldAimFrame.origin.y - tableViewOrigin.y);
        _tableView.frame = tableViewAimFrame;

        //显示最后一个cell
        if (contentHeight > tableViewAimFrame.size.height){
            [_tableView setContentOffset:CGPointMake(0, contentHeight - tableViewAimFrame.size.height)];
        }
    } completion:nil];
}

就这一个方法,也许你会好奇应该在什么时机调用这个方法呢?
咱慢慢说~
首先注册通知,如下

//没错,就是要接收键盘frame将要变化的通知,iSO 5就有了,可以放心使用
//注册完成之后,别忘了在dealloc方法中删除通知哦,否则会引起崩溃
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];

然后实现keyboardWillChangeFrame:方法,如下

- (void)keyboardWillChangeFrame:(NSNotification *)notify{
    NSDictionary    * info = notify.userInfo;
    //动画时间
    CGFloat animationDuration = [info[UIKeyboardAnimationDurationUserInfoKey] floatValue];
    //键盘目标位置
    CGRect  keyboardAimFrame = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue];
    [self keybaordAnimationWithDuration:animationDuration keyboardOriginY:keyboardAimFrame.origin.y];
}

注册通知,实现方法,调用动画,输入框就能紧挨着键盘啦,其实也不麻烦嘛,何必当初怀疑这怀疑那却没有尝试呢?挖的坑最终把自己坑了~

demo是用Masonry布局,然后在动画里修改frame,实际开发过程中使用UITextView作为输入框时需要在旋屏后更新一下约束。
demo地址:https://github.com/NSSONGMENG/KeyboardAnimationDemo


最后,如果你为高度计算而烦恼,可参看链接文章
http://blog.csdn.net/mo_mo123/article/details/53701380
如有疑惑欢迎留言区讨论

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值