重新加载数据后,我可以在我的 tableView 中保持相同的位置吗?

Posted

技术标签:

【中文标题】重新加载数据后,我可以在我的 tableView 中保持相同的位置吗?【英文标题】:Can I keep the same position in my tableView after reloading the data? 【发布时间】:2020-01-13 14:42:30 【问题描述】:

在我 reloadData() 后,我的 tableView 出现问题。它总是滚动到顶部。我不知道我在哪里搞砸了,因为在保持偏移位置之前它工作得很好。

我使用的是自动尺寸。

var currentCount: Int 
   return news.count
 
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 200
 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    if !fetchingMore && indexPath.row == currentCount - 1 
      beginBatchFetched()
   
 

 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    return tableView.estimatedRowHeight
 

 func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat 
    return 200
 
private func beginBatchFetched() 
  fetchingMore = true
  customGetAllNews(serchKey: qKey, tags: tagsAsParameter, cameFromPullToRefresh: false)

private func customGetAllNews(serchKey: String?, tags: [String]? = nil,....) 

  Helper.getAllNews(page: self.currentPage, key: serchKey........)  (data) in
    self.fetchingMore = false

    guard let nws = data?.news else return
    self.currentPage += 1
    self.news.append(contentsOf: nws)

    GlobalMainQueue.async 
      self.tableView.reloadData()
   
 

我还尝试了其他帖子中一些已接受的答案,例如在重新加载之前保存我的表格视图的偏移量,然后设置它,但它不能正常工作,因为我仍然需要滚动一下达到我之前的目标。

另外,我尝试了heightDictionary: [Int : CGFloat] = [:]的方法

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    heightDictionary[indexPath.row] = cell.frame.size.height


override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat 
    let height = heightDictionary[indexPath.row]
    return height ?? UITableViewAutomaticDimension

但是不成功,结果还是一样,跳转到tableview的顶部。

【问题讨论】:

您在哪个设备和 ios 版本上运行此实验?我在 iOS 13 之前的旧 iOS 设备上遇到过这种行为。 最新,iOS 13.xxx 【参考方案1】:

@Mohamed,请查看以下代码并将其放入您的主队列中,而不是重新加载数据。

请检查并告诉我这是否适合您。

GlobalMainQueue.async self.tableView.reloadData()

UIView.setAnimationsEnabled(false)
self.tableView.beginUpdates()
self.tableView.reloadSections(IndexSet(index: 1) as IndexSet, with: 
UITableViewRowAnimation.none)
self.tableView.endUpdates()

【讨论】:

看起来它正在工作。但是你能简单解释一下为什么我必须使用 UIView.setAnimationsEnabled(false) @MohamedLee,这将视图动画设置为 false,因此默认情况下,tableview 在重新加载数据时,tableview 显示动画并通过设置 UIView.setAnimationsEnabled(false) 删除您不使用的动画不想在重新加载期间显示。希望你找到解决办法。确保,如果您在项目中的任何地方使用动画,请将 UIView.setAnimationEnabled 设置为 true 以在任何地方使用动画。只要在你不想显示动画的地方保持这个 false 。 通过这样做我的UIRefreshControl 没有更多的动画 所以,当 tableview 重新加载时,您必须将此属性设置为 true。 在 endUpdates 之后,在 mainQueue 块中将属性设置为 true,当 tableview 尝试重新加载时,视图动画属性设置为 false,因此它会表现良好,并且在 endupdates 之后,再次设置这个为真

以上是关于重新加载数据后,我可以在我的 tableView 中保持相同的位置吗?的主要内容,如果未能解决你的问题,请参考以下文章

用内容重新加载我的 tableView 后,它仍然显示为灰色,直到我点击它..为啥?

Obj-C - 数据重新加载后TableView滚动到底部?

iOS 为啥我的应用程序在重新启动之前不会将数据加载到 tableview 中?

获取异步 JSON 数据后重新加载 tableview

解析查询后在哪里重新加载 UITableView 数据

每次用户签名时,TableView 都会重新加载并添加(重复)原始数据