这不是关于在键盘上升和下降时提升collectionView的问题,该部分工作正常。这是关于collectionView里面的scrollView没有随之而来的。
我有一个视图固定在屏幕的底部,在该视图内我有一个textView。固定在视图顶部的是一个固定在屏幕顶部的collectionView
-top of viewController
collectionView
containerView that contains a textView
-bottom of viewController
当轻触textView的textField时,我会使用一个通知来检测键盘上升和下降的时间。它工作正常,因为collectionView像它应该的那样上下移动。问题是collectionView的内容。如果collectionView的单元格在collectionView上升时填满了屏幕,则它的scrollVIew不会随之升起,因此单元格位于键盘后面。 2张图片如下。
当发送键盘通知时,我尝试更改collectionView的contentInset,scrollIndicatorInsets,并尝试滚动到最后一个单元格,但没有。细胞向上滚动一点点。
@objc fileprivate func keyboardWillShow(notification: Notification) {
guard let keyboardDuration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else { return }
guard let keyboardFrame: NSValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
let keyboardFrame = keyboardFrame.cgRectValue
let keyboardHeight = keyboardFrame.height
containerViewBottomAnchorConstraint?.isActive = false
containerViewBottomAnchorConstraint = containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -keyboardHeight)
containerViewBottomAnchorConstraint?.isActive = true
// I tried this
let item = tableData.count - 1
let indexPath = IndexPath(item: item, section: 0)
if !tableData.isEmpty {
collectionView.scrollToItem(at: indexPath, at: .bottom, animated: true)
}
// I tried this
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: -keyboardHeight, right: 0)
collectionView.contentInset = contentInsets
collectionView.scrollIndicatorInsets = contentInsets
UIView.animate(withDuration: keyboardDuration, animations: {
self.view.layoutIfNeeded()
}) { [weak self](_) in
self?.autoScrollToLastCell() // I tried this
}
}
@objc fileprivate func keyboardWillHide(notification: Notification) {
guard let keyboardDuration = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else { return }
containerViewBottomAnchorConstraint?.isActive = false
containerViewBottomAnchorConstraint = containerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0)
containerViewBottomAnchorConstraint?.isActive = true
UIView.animate(withDuration: keyboardDuration, animations: {
self.view.layoutIfNeeded()
}) { [weak self](_) in
self?.autoScrollToLastCell()
}
}
func autoScrollToLastCell() {
let section = 0
let item = collectionView.numberOfItems(inSection: section) - 1
let index = IndexPath(item: item, section: section)
if item > 0 {
collectionView.scrollToItem(at: index, at: .bottom, animated: true)
}
}
这应该是公认的答案:
在引发键盘时添加侦听器:
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
然后添加此功能:
@objc func handleKeyboardWillShow(notification: Notification) {
collectionView.scrollToItem(at: IndexPath(row: messagesList.count - 1, section: chatSection), at: .top, animated: false)
}
注意:如果您有多个部分,请更改section
值
修复很简单,我所要做的就是将collectionView的内容设置为UIEdgeInsets(top: 0, left: 0, bottom: 8, right: 0)
下面我将底部参数设置为8,这样看起来最后一个单元格的底部和containerView的顶部之间可以有填充
collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 8, right: 0)
为了清楚起见,设置collectionView的contentInset
属性是解决这个问题的原因。它与8分无关。即使它是0,0,0,0它工作正常。 8分只是为了出场/偏好。这里没有任何“神奇数字”来修复任何东西。