我创建了一个带有UICollectionView
和InputAccessoryView
的评论页面,该页面的底部显示了评论单元格和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()
})
}