Swift - 如何在 tableView 顶部插入单元格保持偏移和滚动惯性

Posted

技术标签:

【中文标题】Swift - 如何在 tableView 顶部插入单元格保持偏移和滚动惯性【英文标题】:Swift - How can insert cell at tableView top keep offset and scroll inertia 【发布时间】:2018-03-23 04:08:59 【问题描述】:

我使用下面的代码来更新我的tableView

func scrollViewDidScroll(_ scrollView: UIScrollView) 
    //Load more cell
    if tableView.contentOffset.y < 100 
        let beforeTableViewContentHeight = tableView.contentSize.height
        let beforeTableViewOffset = tableView.contentOffset.y
        let moreDataArray = getAllMessages()

        for message in moreDataArray.reversed() 
            dataArray.insert(message, at: 0)
        

        DispatchQueue.main.async 
            self.tableView.reloadData()
            self.tableView.layer.layoutIfNeeded()
            let insertCellHeight = beforeTableViewOffset + (self.tableView.contentSize.height - beforeTableViewContentHeight)
            let newOffSet = CGPoint(x: 0, y: insertCellHeight)
            self.tableView.setContentOffset(newOffSet, animated: false)
        
    

但是当插入单元格和reloadData()时,滚动惯性会停止。

whatsapp 之类的如何插入单元格到顶部保持偏移和滚动惯性。

This is example

前 5 秒,table 很短,当我快速向上滚动和手指伸出时(如 android 滚动状态 scroll_state_fling),顶部插入更多内容,同时可以保持偏移和滚动惯性,太神奇了,我该怎么做?

【问题讨论】:

self.tableView.setContentOffset(newOffSet, animated: false)更改为self.tableView.contentOffset = newOffSet 谢谢回复,我试了一下,好像没什么区别,滚动惯性还是停止了。 【参考方案1】:

为了保持惯性,您需要确保数据的加载和重新加载被调用一次。您必须放置一个布尔变量来阻止多次触发加载更多,例如

var isLoadMore = true
func scrollViewDidScroll(_ scrollView: UIScrollView) 
        //Load more cell
        if tableView.contentOffset.y < 100, self.isLoadMore 
            self.isLoadMore = false
            let beforeTableViewContentHeight = tableView.contentSize.height
            let beforeTableViewOffset = tableView.contentOffset.y
            let moreDataArray = getAllMessages()

            for message in moreDataArray.reversed() 
                dataArray.insert(message, at: 0)
            

            DispatchQueue.main.async 
                self.tableView.reloadData()
                self.tableView.layer.layoutIfNeeded()
                let insertCellHeight = beforeTableViewOffset + (self.tableView.contentSize.height - beforeTableViewContentHeight)
                let newOffSet = CGPoint(x: 0, y: insertCellHeight)
                self.tableView.contentOffset = newOffSet
                self.isLoadMore = true
            
        
  

我发现在 tableView 中引入更多功能的负载的最佳位置是tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 方法。在此方法中,您可以检查 indexPath 而不是 contentOffSet

【讨论】:

谢谢回复,我试试看,但不管使用'willDisplay'或'scrollViewDidScroll'滚动惯性还是停止,所以很烦恼。 我加了isLoadMore,还是这样 在github.com/kaushaldeo/CodeSnippets/blob/master/… 处查看代码,该代码运行良好。 我将解决方案复制并粘贴到一个新项目中进行测试,tebleview 上没有任何内容显示,我是否应该在实现代码时遗漏任何内容?

以上是关于Swift - 如何在 tableView 顶部插入单元格保持偏移和滚动惯性的主要内容,如果未能解决你的问题,请参考以下文章

当tableview在顶部时如何进行分页

拖动到视图顶部时,UILongPressGestureRecognizer 在 tableview 中崩溃 - SWIFT

如何在按钮按下时转到 tableView 的顶部

旋转期间 searchController.active 之后,Swift searchBar 与 tableView 的顶部分离

Swift:如何在 tableView 中模糊点击单元格

如何在 Swift 中使用两个 TableView 设计动态布局