Can I keep the same position in my tableView after reloading the data?

1.5k views Asked by At

I'm having issues with my tableView after I reloadData(). It always scrolls to the top. I don't know where I've messed it up since before it worked very fine maintaining the offset position.

I'm using an automatic dimension.

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

I've also tried some accepted answers from other posts like saving the offset of my table view right before the reload and after that set it, but it doesn't work as it should, because I still need to scroll a bit to get to the point I was before.

Also, I've tried the method with the 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
}

but unsuccessfully, the result was the same, jumps to the top of the tableview.

1

There are 1 answers

8
Vikash Sinha On

@Mohamed, please have a look with the below code and put this inside your mainqueue instead of reloading the data.

Please check and let me know if this works for you.

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