inputAccessoryView未激活时无高度致内容遮挡问题求助
解决方案
问题根源在于你固定了collectionView的底部内边距,而inputAccessoryView的高度在未激活和激活状态下(键盘弹出/收起)会变化,导致内边距要么不足要么冗余。核心思路是动态根据inputAccessoryView的高度以及键盘状态调整collectionView的内边距。
步骤1:修改初始化配置
在viewDidLoad中,移除固定的底部内边距设置,改为只保留顶部内边距,并关闭系统自动内边距调整,方便手动控制:
override func viewDidLoad() { super.viewDidLoad() collectionView?.register(ChatMessageCell.self, forCellWithReuseIdentifier: cellId) // 只保留顶部内边距,底部内边距后续动态设置 collectionView?.contentInset = UIEdgeInsets(top: 8, left: 0, bottom: 0, right: 0) collectionView?.backgroundColor = .moonNavy collectionView?.alwaysBounceVertical = true collectionView?.keyboardDismissMode = .interactive // 关闭系统自动内边距调整,改为手动控制 collectionView?.contentInsetAdjustmentBehavior = .never loadCurrentUserObject() setupKeyboardObserve() }
步骤2:添加高度跟踪与内边距更新
添加变量跟踪inputAccessoryView的当前高度,并在布局变化时更新内边距:
// 跟踪inputAccessoryView的当前高度 private var accessoryViewCurrentHeight: CGFloat = 0 override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() guard let accessoryView = inputAccessoryView else { return } let newHeight = accessoryView.frame.height // 高度变化时才更新内边距,避免重复操作 if newHeight != accessoryViewCurrentHeight { accessoryViewCurrentHeight = newHeight updateCollectionViewBottomInset(withKeyboardHeight: 0) } } // 统一更新collectionView底部内边距的方法 private func updateCollectionViewBottomInset(withKeyboardHeight keyboardHeight: CGFloat) { guard var inset = collectionView?.contentInset else { return } // 底部内边距 = 键盘高度 + inputAccessoryView高度 + 原有间距8 inset.bottom = keyboardHeight + accessoryViewCurrentHeight + 8 collectionView?.contentInset = inset collectionView?.scrollIndicatorInsets = inset }
步骤3:处理键盘弹出/收起事件
修改键盘通知监听方法,在键盘状态变化时更新内边距:
func setupKeyboardObserve() { NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) } @objc private func keyboardWillShow(_ notification: Notification) { guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } let keyboardHeight = keyboardFrame.height updateCollectionViewBottomInset(withKeyboardHeight: keyboardHeight) } @objc private func keyboardWillHide(_ notification: Notification) { updateCollectionViewBottomInset(withKeyboardHeight: 0) }
步骤4:确保inputAccessoryView初始化时高度正确
在inputAccessoryView的getter方法末尾添加布局强制刷新,确保初始化时就能获取到正确高度:
override var inputAccessoryView: UIView? { if (_inputAccessoryView == nil ){ // ... 你的原有初始化代码 textViewDidChange(textView) // 强制刷新布局,计算正确高度 _inputAccessoryView.layoutIfNeeded() } return _inputAccessoryView }
关键说明
- 关闭
contentInsetAdjustmentBehavior = .never是为了避免系统自动调整内边距与手动设置冲突; viewDidLayoutSubviews会在每次布局变化时触发,确保inputAccessoryView高度变化后能及时更新内边距;- 统一用
updateCollectionViewBottomInset方法处理内边距,避免代码重复; - 初始化时强制刷新
inputAccessoryView布局,保证初始高度计算正确,解决未激活时的遮挡问题。
内容的提问来源于stack exchange,提问作者zak
相关产品推荐
相关产品推荐

