Swift - 如何在键盘抬起时滚动collectionView的内容

问题描述 投票:0回答:1

这不是关于在键盘上升和下降时提升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)
    }
}

在键盘上升之前enter image description here

键盘上升后,collectionView已启动,但它的内容不是enter image description here

ios swift uiscrollview uicollectionview keyboard-events
1个回答
2
投票

这应该是公认的答案:

在引发键盘时添加侦听器:

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


-2
投票

修复很简单,我所要做的就是将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分只是为了出场/偏好。这里没有任何“神奇数字”来修复任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.