UITableView底部约束动画失效 键盘弹出时无法上移
约束失效的核心原因与修复方案
为什么你的代码完全没有效果
- 约束常量的方向搞反了
你写的约束逻辑是tableView.bottom = view.bottom * 1 + constant,AutoLayout的计算规则是:正值的constant会让tableView的底部往参照点(view的底边缘)的屏幕下方偏移,也就是直接跑到屏幕可视区域外面;只有负值的constant,才会让tableView的底部向上移动、回到屏幕里。
你现在把constant设为键盘高度的正值,相当于把tableView的底部往屏幕外推,加上初始状态下tableView已经铺满整个view,这个偏移带来的位置变化根本看不到,自然没有动画效果。 - 约束的参照对象搭错了
你现在让tableView的底部直接绑在view的最底端,但界面上还有一个固定在view底端的messageTextView:初始状态tableView是完全盖住messageTextView的下层的,就算你把constant的符号改对,tableView上移后空出来的底部区域,还是会和不动的messageTextView叠在一起,逻辑完全不通。 - 键盘高度的取值没有做坐标系换算
通知里拿到的info.endFrame是全局屏幕坐标系的位置,在带安全区的iPhone上,直接拿这个高度当偏移量,会算出来的位置和实际需要的偏移量有偏差。
正确的实现步骤
- 删掉原来那个直接绑view底的tableViewBottomConstraint,重新设置约束:让tableView的底部直接和messageTextView的顶部对齐(间距为0)。这样messageTextView位置变了,tableView会自动跟着调整高度,根本不需要单独管tableView的约束。
- 给messageTextView的底部约束加个属性引用,比如叫
messageTextViewBottomConstraint,初始约束设为messageTextView的底部和view的安全区底部对齐,常量为0。 - 收到键盘弹起通知时,先把键盘的frame转换到当前view的坐标系下,算出键盘顶部离view底部的实际高度,把
messageTextViewBottomConstraint.constant设为对应的负值——也就是把messageTextView整个抬到键盘的上方位置。键盘收起的时候,把这个常量改回0就行。 - 把通知里带的键盘动画时长、动画曲线转成UIView动画的对应参数,在动画块里调用
view.layoutIfNeeded(),就能同步完成messageTextView和tableView的联动动画。
内容的提问来源于stack exchange,提问作者Kex
相关产品推荐
相关产品推荐

