如何在没有keyboardDismissMode的情况下实现在滚动视图中向下拖动键盘?

时间:2019-02-04 11:11:11

标签: swift uicollectionview keyboard inputaccessoryview

我创建了一个带有UICollectionViewInputAccessoryView的评论页面,该页面的底部显示了评论单元格和textView(带有提交按钮)。

我想在屏幕出现时向上移动屏幕,以保持集合视图当前单元格的位置,而无需自动滚动到某些单元格。

因此,我通过在发生y通知时更改集合视图的top contentInset坐标和keyboardWillShow来做到这一点,并且效果很好。

但是,问题出在keyboardDismissMode属性中,我赋予.interactive值来向下拖动键盘。 在拖动键盘的过程中,集合视图和键盘之间会出现一个白色的间隙。 另外,如果在向下拖动的同时再次向上拖动键盘,则白色间隙会变大,屏幕将停止。

因此,我将底部视图(内部的textview + submit按钮)实现为自定义视图,而不是使用inputAccessoryView。 为防止收藏视图和底视图之间出现间隙,请使用自动布局将收藏视图的底部和底视图的顶部粘贴。 当前keyboardDismissMode已被删除,因为它仅向下拖动键盘,而不是底部视图。

问题是,如何在没有keyboardDismissMode的情况下实现在滚动视图中向下拖动键盘?

inputAccessoryView开头:

@objc private func keyboardWillChange(_ sender: NSNotification) {
    guard commentsForPost.count > 0 else { return }
    guard let keyboardBeginFrame = (sender.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue else { return }
    guard let keyboardEndFrame = (sender.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return }

    guard !keyboardBeginFrame.equalTo(keyboardEndFrame) else { return }

    switch sender.name {
    case UIResponder.keyboardWillShowNotification:
        self.collectionView.contentInset.top = keyboardEndFrame.height
        self.collectionView.frame.origin.y -= keyboardEndFrame.height
    case UIResponder.keyboardWillHideNotification:
        self.collectionView.frame.origin.y = 0
        self.collectionView.contentInset.top = 0
    default: break
    }

    guard let duration = ((sender.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey]) as? NSNumber)?.doubleValue else { return }
    UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
        self.view.layoutIfNeeded()
    })

    collectionView.scrollIndicatorInsets = collectionView.contentInset
}

自定义底视图的实现:

@objc private func keyboardWillChange(_ sender: NSNotification) {
    ... // Most of the same.
    switch sender.name {
    case UIResponder.keyboardWillShowNotification:
        collectionViewTopAnchor?.constant = -keyboardEndFrame.height
        containerViewBottomAnchor?.constant = -keyboardEndFrame.height
        // For removing a little gap.
        if let lastCellAttributes = self.collectionView.layoutAttributesForItem(at: IndexPath(item: self.commentsForPost.count - 1, section: 0)) {
            self.collectionView.contentInset.top += lastCellAttributes.frame.height * 2.5
            self.collectionView.contentOffset.y += lastCellAttributes.frame.height
        }
    case UIResponder.keyboardWillHideNotification:
        collectionViewTopAnchor?.constant = 0
        containerViewBottomAnchor?.constant = 0
        if let lastCellAttributes = self.collectionView.layoutAttributesForItem(at: IndexPath(item: self.commentsForPost.count - 1, section: 0)) {
            self.collectionView.contentInset.top = 0
            self.collectionView.contentOffset.y -= lastCellAttributes.frame.height
        }
    default: break
    }

    UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: {
        self.view.layoutIfNeeded()
    })
}

0 个答案:

没有答案