Ios 当键盘出现时,按固定常数平滑地向上滚动tableview,以便最后一个单元格仍然可见

Ios 当键盘出现时,按固定常数平滑地向上滚动tableview,以便最后一个单元格仍然可见,ios,swift,uitableview,autolayout,uikeyboard,Ios,Swift,Uitableview,Autolayout,Uikeyboard,当键盘出现时,我将最底部的视图向上移动一个常数。但由于这一点,UITableView的高度也降低了,以前可见的单元格不再可见。我想做的是将表格视图向上滚动一个与键盘高度相等的高度,这样至少可以看到最后的消息,就像键盘出现之前一样 在左边的图像中,最后一个半可见的黄色单元格也应该像右边的一样可见 我认为将表格视图滚动一个等于键盘高度的偏移量应该可以。但是我找不到一种方法来任意滚动一个tableview。我试图弄乱内容偏移量的y值,但这造成了奇怪的行为。我还非常感谢过渡是否平滑,以便表视图单元格看起

当键盘出现时,我将最底部的视图向上移动一个常数。但由于这一点,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)
    }
}

编辑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,
            delay: TimeInterval(0),
            options: animationCurve,
            animations: { self.view.layoutIfNeeded() },
            completion: nil)
    }
}

编辑1 这将按预期移动单元,但动画会出现起伏,单元丢失,与动画的其余部分不一致。是否有方法覆盖动画曲线和其他属性?我是否应该将其放入
ui视图中。为
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(u:animated:)
。您的意思是这样的:`discussionChatView.discussionTableView.setContentOffset(CGPoint(x:0,y:offset),动画:true)`?同时添加
discussionChatView.discussionTableView.contentInset.bottom=-1*偏移量也没有帮助。现在我已经将桌面视图按键盘高度向上移动,并从下方添加与键盘高度相等的填充!没有动画滚动条你能看一下我的编辑吗?我没有足够的时间来深入查看你的代码,但是
contentInset.bottom
应该是肯定的。您必须对这些值进行处理,才能找到正确的解决方案。确保考虑到与屏幕相关的表视图的
y
值。祝你好运请看这个?只有7秒。我已经让它几乎工作了。只是有点起伏。