如何解决当键盘出现时,按固定常量平滑向上滚动表格视图,以便最后一个单元格仍然可见
当键盘出现时,我将最底部的视图向上移动一个常数。但由于这个原因, UITableView 的高度也降低了,以前可见的单元格不再可见。我想要做的是将表格视图向上滚动一个等于键盘高度的高度,这样至少最后的消息会像键盘出现之前一样可见。
左侧图像中半可见的最后一个黄色单元格也应该像右侧那样可见。
我认为以等于键盘高度的偏移量滚动表格视图应该可行。但是我找不到任意滚动 tableview 的方法。我尝试弄乱内容偏移的 y 值,但这会产生奇怪的行为。我也非常感谢过渡是否平滑,以便表格视图单元格看起来像随着键盘一起向上移动。类似于所有其他聊天应用程序如何设置这种转换。
编辑 3
好的,所以我已经计算出键盘出现和消失的数学方法。但是在跟随动画曲线的其余部分之前,动画仍然会跳跃一点。我该如何解决?
NotificationCenter.default.addobserver(self,selector: #selector(keyboardNotification),name: NSNotification.Name.UIKeyboardWillChangeFrame,object: nil)
extension discussionsViewController {
@objc func keyboardNotification(notification: NSNotification) {
guard let userInfo = notification.userInfo else { return }
let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let endFrameY = endFrame?.origin.y ?? 0
let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.Animationoptions.curveEaseInOut.rawValue
let animationCurve:UIView.Animationoptions = UIView.Animationoptions(rawValue: animationCurveRaw)
let offset = -1 * (endFrame?.size.height ?? 0.0)
if endFrameY >= UIScreen.main.bounds.size.height {
self.discussionsMessageBoxBottomAnchor.constant = 0.0
let yOffset = discussionChatView.discussionTableView.contentOffset.y
discussionChatView.discussionTableView.contentOffset.y = yOffset + 2 * offset
} else {
self.discussionsMessageBoxBottomAnchor.constant = offset
let yOffset = discussionChatView.discussionTableView.contentOffset.y
discussionChatView.discussionTableView.contentOffset.y = yOffset - offset
}
discussionChatView.discussionTableView.scrollIndicatorInsets = discussionChatView.discussionTableView.contentInset
UIView.animate(
withDuration: duration,delay: TimeInterval(0),options: animationCurve,animations: { self.view.layoutIfNeeded() },completion: nil)
}
}
Screen recording of choppy animation
编辑 2
键盘出现时的动画现在好多了。单元格以相同的动画属性向上移动。虽然当最后一个单元格在底部时仍然有一个跳跃。当键盘消失时,我仍然无法计算偏移的数学方法。以及如何让动画变得更流畅。
extension discussionsViewController {
@objc func keyboardNotification(notification: NSNotification) {
guard let userInfo = notification.userInfo else { return }
let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let endFrameY = endFrame?.origin.y ?? 0
let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.Animationoptions.curveEaseInOut.rawValue
let animationCurve:UIView.Animationoptions = UIView.Animationoptions(rawValue: animationCurveRaw)
let offset = -1 * (endFrame?.size.height ?? 0.0)
if endFrameY >= UIScreen.main.bounds.size.height {
self.discussionsMessageBoxBottomAnchor.constant = 0.0
//STILL NOT AS EXPECTED
let yOffset = discussionChatView.discussionTableView.contentOffset.y
discussionChatView.discussionTableView.contentOffset.y = yOffset - offset
} else {
self.discussionsMessageBoxBottomAnchor.constant = offset
let yOffset = discussionChatView.discussionTableView.contentOffset.y
discussionChatView.discussionTableView.contentOffset.y = yOffset - offset
}
UIView.animate(
withDuration: duration,completion: nil)
}
}
编辑 1
这是按预期移动单元格,但动画不连贯,单元格丢失且与动画的其余部分不符。有没有办法覆盖动画曲线和其他属性?我应该把它放在 UIView.animate
里面,并为 setContentOffset
设置动画假吗?我不知道如何完全解决这个问题。
if endFrameY >= UIScreen.main.bounds.size.height {
self.discussionsMessageBoxBottomAnchor.constant = 0.0
self.discussionChatView.discussionTableView.contentInset.bottom = 0
} else {
let offset = -1 * (endFrame?.size.height ?? 0.0)
self.discussionsMessageBoxBottomAnchor.constant = offset
// discussionChatView.discussionTableView.contentInset.bottom = -1 * offset
let yOffset = discussionChatView.discussionTableView.contentOffset.y
discussionChatView.discussionTableView.setContentOffset(CGPoint(x: 0,y: yOffset - offset),animated: true)
}
解决方法
你差点就明白了。
滚动表格视图不起作用,因为它已经位于内容的边缘,但您可以使用 contentInset
来“填充”内容。
您要做的是计算键盘进入表格视图的距离,并将该值设置为 contentInset.bottom
。这将在表格视图的底部添加一个“空白区域”。
我不知道这是否会自动滚动您的视图,但如果不是这种情况,那么您可以使用 setContentOffset(_:animated:)
。在桌子上。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。