2017-05-22 88 views
0

后顶部我有动力单元的高度在我的tableView的UITableView动态细胞高度滚动调用reloadData

tableView.rowHeight = UITableViewAutomaticDimension 
tableView.estimatedRowHeight = 100 

我想要做的一样WhatsApp的应用程序(分页),我想加载25 25行,所以当在顶部的用户滚动,我想加载新的数据,但我想保持滚动的同一位置,这里是我做过什么

func scrollViewDidScroll(_ scrollView: UIScrollView) { 
    if isMore && scrollView.contentOffset.y == 0 { 
     loadMore() // function that add new data in my model 
     self.tableView.reloadData() 
    } 
} 

我已经是后我达到我的tableview的顶部它调用reloadData但问题tableView滚动到UP

我测试器这样的一些其他的解决方案:

var cellHeights: [IndexPath : CGFloat] = [:] 

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 
    cellHeights[indexPath] = cell.frame.size.height 
} 

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { 
    guard let height = cellHeights[indexPath] else { return 70.0 } 
    return height 
} 

但仍然没有工作

+0

默认情况下,表视图上的'.reloadData()'不会**改变表的滚动位置。也许在你的'loadMore()'或其他一些函数正在改变表视图​​属性? – DonMag

+0

是的,因为我使用动态单元格高度UITableViewAutomaticDimension – OuSS

+0

嗯...你说*“当用户滚动顶部,我想加载新的数据”* ...所以你想添加行上面的第零行? – DonMag

回答

0

如果你重装表中添加更多的数据,下面的函数调用重载然后后保留滚动位置。

tableview.scrollToRow(at: indexPath, at: .middle, animated: true) 

here indexPath是重新加载前的最后一个单元格的indexPath。

+0

这个功能不保持完全相同的位置 – OuSS

+0

你可以尝试通过更改UITableViewScrollPosition? – user3608500

+0

我如何获得这个职位? – OuSS

0

tableView:cellForRowAt当您检测到indexPath正在接近最后一个元素(当indexPath.row越来越接近yourArray.count)时,查询更多项目。当你有它们时,把它们添加到你的数据源(数组,或者任何它,你拥有表中所有对象的地方)并重新加载表视图。表格视图应该显示新的项目,并且用户可以继续滚动而不做特别的事情。

您不应该等到tableView:cellForRowAt被调用为最后一个单元格,因为如果您需要调用服务器来获取更多的项目,用户将不得不等待。 Whatsapp的滚动速度很快,因为他们在滚动到最后一个元素之前下载了这些项目(前一段时间它在最后停止了,但现在它们可能会提前获取新项目)。

请记住,25个项目可能太少,它的网络速度很慢,用户可能会滚动显示更多项目之前所需的项目,并且需要等待,这不是一个好的用户体验。模拟一个慢速的网络连接,看看你的应用程序联系服务器时是否有足够的25个项目滚动浏览(取决于网络速度,请求和响应大小,服务器响应你的请求的速度等)。

+0

是我所做的只是即时通讯测试indexPath.row == 0因为我想加载数据在顶部而不是像whatsapp底部,但问题是因为我有动态单元格高度'UITableViewAutomaticDimension'当我调用tableview的reloadData,滚动的位置总是在行= 0像它重绘表 – OuSS

0

我在消息传递应用程序中遇到了同样的问题。下面是我如何解决它:

  1. 在数据源阵列分配一个唯一messageId消息

  2. cellForRow:中,我将第一行的messageId保存在名为messageIdFirst的变量中。

    if(indexPath.row == 0){ 
        messageIdFirst = message.id! 
    } 
    
  3. loadMore()方法中,我检查哪个当前indexpath行具有相同的MESSAGEID在现在更新的数据源阵列。

    if(message.id == messageIdFirst){ 
        previousTopIndexPath = i 
    } 
    

    ,其中i是在数据源阵列,其指数,其具有相同的messageId.

  4. 现在,我滚动到previousTopIndexPath这样的:

    tableview.scrollToRow(at: previousTopIndexPath, at: .middle, animated: true)

注1:A这是不是在UITableView高效工作,我最终使用相同的解决方案使用UICollectionView

注2:虽然这并顺利工作,我知道必须存在一个更清洁的方式来做到这一点。