TableView输入键盘遮挡问题:同步滑动与动画匹配求助
解决TableView输入框被键盘遮挡且动画不同步问题
核心问题分析
你遇到的是键盘弹出时TableView上滑动画和键盘动画不同步、contentInset调整过快的问题,本质是没有对齐键盘的动画时长与曲线,同时未正确计算偏移距离。
具体修复步骤
监听正确的键盘通知
务必监听UIKeyboardWillShowNotification和UIKeyboardWillHideNotification,不要使用UIKeyboardDidShowNotification/UIKeyboardDidHideNotification——前者能获取键盘的完整动画参数,是同步的关键。匹配键盘的动画参数
从通知的userInfo中提取键盘的动画时长、动画曲线,用这些参数驱动TableView的动画,而非默认动画参数:@objc func keyboardWillShow(_ notification: Notification) { guard let userInfo = notification.userInfo, let keyboardFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as? CGRect, let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? TimeInterval, let curveRawValue = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt else { return } let keyboardHeight = keyboardFrame.height // 将UIViewAnimationCurve转换为UIView.AnimationOptions let animationOptions = UIView.AnimationOptions(rawValue: curveRawValue << 16) UIView.animate(withDuration: duration, delay: 0, options: animationOptions, animations: { self.tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0) self.tableView.scrollIndicatorInsets = self.tableView.contentInset }, completion: nil) }让激活的输入框自动滚动到可视区域
在输入框开始编辑时,找到其所在Cell并滚动到合适位置,确保不被键盘遮挡:func textFieldDidBeginEditing(_ textField: UITextField) { guard let cell = textField.superview?.superview as? UITableViewCell, let indexPath = tableView.indexPath(for: cell) else { return } // 滚动到Cell底部,配合contentInset确保完全可见 tableView.scrollToRow(at: indexPath, at: .bottom, animated: true) }若需要更精准的同步,可将滚动操作放在键盘动画的
completion闭包中执行。键盘隐藏时恢复原始状态
同样使用匹配的动画参数恢复contentInset:@objc func keyboardWillHide(_ notification: Notification) { guard let userInfo = notification.userInfo, let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? TimeInterval, let curveRawValue = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt else { return } let animationOptions = UIView.AnimationOptions(rawValue: curveRawValue << 16) UIView.animate(withDuration: duration, delay: 0, options: animationOptions, animations: { self.tableView.contentInset = UIEdgeInsets.zero self.tableView.scrollIndicatorInsets = self.tableView.contentInset }, completion: nil) }排查动画冲突
检查代码中是否有其他修改TableViewcontentInset或触发滚动的逻辑,确保只有键盘通知回调处理该操作,避免动画叠加导致的不同步。
关键注意事项
- 必须使用
WillShow/WillHide通知,DidShow/DidHide无法获取前置动画参数,会导致同步失效 - 动画曲线需左移16位转换,因为
UIKeyboardAnimationCurveUserInfoKey返回的是UIViewAnimationCurve原始值,需转为UIView.AnimationOptions格式 - 若使用Auto Layout,不要手动调整TableView的frame,仅通过
contentInset调整滚动区域
内容的提问来源于stack exchange,提问作者IDontKnow
相关产品推荐
相关产品推荐

