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

来源:互联网 发布:剑灵捏脸数据图灵族男 编辑:程序博客网 时间:2024/05/12 09:15

在上家公司做项目的时候,布局使用的是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 0
原创粉丝点击