当键盘出现时,通过固定常数平滑地向上滚动tableview,因此最后一个单元格仍然可见 [英] Smoothly scrolling tableview up by fixed constant when keyboard appears so last cells are still visible

查看:70
本文介绍了当键盘出现时,通过固定常数平滑地向上滚动tableview,因此最后一个单元格仍然可见的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

出现键盘时,我将最底端的视图向上移动了一个常数.但是由于这个原因,UITableView的高度也降低了,并且以前可见的单元格不再可见.我想做的是将表格视图向上滚动一个高度,该高度等于键盘的高度,这样至少最后一条消息将像键盘出现之前一样可见.

When the keyboard appears, I am shifting the bottom-most view up by a constant. But due to this the hight of the UITableView also reduces and the cells that were previously visible are no longer visible. What I want to do is scroll the table view up by a height equal to the keyboard's height so that at least the last messages will be visible like they were before the keyboard appeared.

在左侧图像中最后可见的最后一个黄色单元格也应该像在右侧一样可见.

The last yellow cell that was half-visible in the image on left should be visible like that on the right too.

我认为以等于键盘高度的偏移量滚动表格视图应该可以.但是我找不到任意滚动表格视图的方法.我尝试弄乱内容偏移量的y值,但这造成了奇怪的行为.我也非常感谢过渡是否顺利,以便表格视图单元格看起来像它们随着键盘向上移动一样.所有其他聊天应用程序如何设置此过渡的类型.

I think scrolling the table view by an offset equal to keyboard height should work. But I can't find a method to arbitrarily scroll a tableview. I tried messing with y value of content offset but that is creating odd behavior. I would also really appreciate if the transition would be smooth so the table view cells look like they are moving up along with the keyboard. Kind of how all the other chat apps set this transition up.

好的,所以我已经弄清楚了键盘出现和消失的数学原理.但是在跟随动画的其余曲线之前,动画仍然会跳一点.我该如何解决?

Okay so I have figured the math out for both keyboard appearing and disappearing. But the animation still jumps a bit before following the rest of the animation's curve. How can I fix that?

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

现在出现键盘时的动画效果要好得多.单元格以相同的动画属性向上移动.尽管最后一个单元格在底部时仍会跳起来.当键盘消失时,我仍然无法弄清楚偏移量的数学运算.以及动画如何变得更平滑.

Screen recording of choppy animation


EDIT 2

The animation when the keyboard appears is a lot better now. The cells move up with the same animation properties. Though still there is a jump up when the last cell is at the bottom. I am still having trouble figuring out the math for offset when the keyboard will disappear. And also how the animation can get smoother.

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

这将按预期移动单元格,但是动画不稳定,缺少的单元格与动画的其余部分不符.有没有办法覆盖动画曲线和其他属性?是否应将setContentOffset的动画false放在UIView.animate中?我不确定如何完全解决这个问题.

EDIT 1

This is shifting the cells as expected, but the animation is choppy with cells going missing and not in line with the rest of the animation. Is there a way to override the animation curve and other properties? Should I put this inside UIView.animate with animated false for setContentOffset? I am not sure how to work this out completely though.

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

推荐答案

您几乎明白了.

滚动表格视图将不起作用,因为它已经位于内容的边缘,但是您可以填充"(Pad)内容使用contentInset.

Scrolling the table view won't work because it's already at the edge of the content, but you can "pad" the content using contentInset.

您要做的是计算键盘到表视图的距离,并将该值设置为contentInset.bottom.这将添加一个空白".在表格视图的底部.

What you'll want to do is to calculate how far into the table view the keyboard is, and set that value to contentInset.bottom. This will add a "blank space" at the bottom of the table view.

我不知道这是否会自动滚动视图,但是如果不是这样,则可以使用setContentOffset(_:animated:).在桌子上.

I don't know if that will automatically scroll your view, but if that's not the case then you can use setContentOffset(_:animated:). on the table.

这篇关于当键盘出现时,通过固定常数平滑地向上滚动tableview,因此最后一个单元格仍然可见的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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