Swift - 如何在键盘抬起时滚动 collectionView 的内容 [英] Swift -How to scroll the collectionView's contents when the keyboard is raised

查看:36
本文介绍了Swift - 如何在键盘抬起时滚动 collectionView 的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这不是在键盘升降时升高 collectionView 的问题,这部分工作正常.这是关于 collectionView 中的 scrollView 没有随之上升.

This isn't a question about raising the collectionView when the keyboard rises and lowers, that part works fine. This is about the scrollView inside the collectionView not rising with it.

我有一个固定在屏幕底部的视图,在该视图中我有一个 textView.固定在视图顶部的是一个固定在屏幕顶部的 collectionView

I have a view pinned to the bottom of the screen and inside that view I have a textView. Pinned to the top of the view is a collectionView that's pinned to the top of the screen

-top of viewController
    collectionView
    containerView that contains a textView
-bottom of viewController

当 textView 的 textField 被点击时,我使用一个通知来检测键盘何时上升和下降.它工作正常,因为 collectionView 像它应该的那样上下移动.问题是 collectionView 的内容.如果 collectionView 的单元格在 collectionView 上升时填满屏幕,则其 scrollVIew 不会随之上升,因此单元格位于键盘后面.下面两张图片.

When the textView's textField is tapped I use a notification which detects when the keyboard rises and lowers. It works fine because the collectionView goes up and down like it's supposed to. The problem is the collectionView's contents. If the collectionView's cells fill the screen when the collectionView rises up it's scrollVIew doesn't raise with it so the the cells are behind the keyboard. 2 pics below.

当发送键盘通知时,我尝试更改 collectionView 的 contentInset、scrollIndicatorInsets,并尝试滚动到最后一个单元格,但什么也没有.单元格只是向上滚动一点.

When the keyboard notification is sent I tried changing the collectionView's contentInset, scrollIndicatorInsets, and tried scrolling to the last cell but nothing. The cells just scroll up a tad bit.

@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)
    }
}

在键盘升起之前

键盘抬起后,collectionView 出现了,但它的内容没有

推荐答案

修复很简单,我所要做的就是将 collectionView 的内容插入设置为 UIEdgeInsets(top: 0, left: 0, bottom: 8, 右:0)

The fix was easy, all I had to do was set the collectionView's content inset to UIEdgeInsets(top: 0, left: 0, bottom: 8, right: 0)

下面我将底部参数设置为 8,这样看起来最后一个单元格的底部和 containerView 的顶部之间可以有填充

Below I set the bottom argument to 8 just so it appears that the last cell can have padding between its bottom and the the containerView's top

collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 8, right: 0)

为清楚起见,设置 collectionView 的 contentInset 属性是解决此问题的方法.与8分无关.即使是 0,0,0,0 它也能正常工作.8 分只是为了外观/偏好.这里没有使用任何魔术数字"来解决任何问题.

For clarity setting the collectionView’s contentInset property is what fixed this problem. It has nothing to do with the 8 points. Even it was 0,0,0,0 it worked fine. The 8 points was just for appearance/preference. There aren’t any "magic numbers" used here to fix anything.

这篇关于Swift - 如何在键盘抬起时滚动 collectionView 的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆