1

I have a UITableView with many cells.
Each cells following it's contents have dynamic height.
But I notice that UITableView sometimes don't scroll the last indexPath when I enter this viewController.
Have any idea to fix it.

tableView.estimatedRowHeight = 200.0
tableView.rowHeight = UITableViewAutomaticDimension

let bottomOffSet = CGPoint(x: 0, y: self.tableView.contentSize.height - self.tableView.bounds.size.height)
self.tableView.setContentOffset(bottomOffSet, animated: false)

PS: I don't want to use "scrollToRow", because it would trigger tableview's function "cellForRowAtIndexPath" many times than "setContentOffset".

tableView.scrollToRow(at: IndexPath(row: contents.count - 1, section: 0), at: .top, animated: animated)
Sarabjit Singh
  • 1,814
  • 1
  • 17
  • 28
tolerate_Me_Thx
  • 387
  • 2
  • 7
  • 21
  • I don't understand how setting `tableView's` `contentOffset` will scroll to last index path? What exactly are you trying to achieve. – PGDev Jan 04 '18 at 06:55
  • Possible duplicate of [How to scroll to the bottom of a UITableView on the iPhone before the view appears](https://stackoverflow.com/questions/2770158/how-to-scroll-to-the-bottom-of-a-uitableview-on-the-iphone-before-the-view-appea) – Arun Kumar Jan 04 '18 at 06:59
  • Possible duplicate of [iOS TableView reload and scroll top](https://stackoverflow.com/questions/48017955/ios-tableview-reload-and-scroll-top) – AshvinGudaliya Jan 04 '18 at 07:22
  • @PGDev just like a chat app's chat view, I want to scroll to the newest message. – tolerate_Me_Thx Jan 04 '18 at 07:23
  • Why don't you simply use `scrollToRow(at indexPath: IndexPath, at scrollPosition: UITableViewScrollPosition, animated: Bool)` ? It the straight forward way to achieve that. And yes `cellForRowAtIndexPath ` is called multiple times due to `tableViewCell's` reusability if the cell is not already visible. It will be called in every case whenever a cell is reused. – PGDev Jan 04 '18 at 07:31
  • I don't think it's duplicate, because they don't mention about dynamic height cell situation. – tolerate_Me_Thx Jan 04 '18 at 07:32
  • @PGDev I don't like use "scrollToRow" , because if I have 100 messages, it will trigger "cellForRow" 100 times. So, I want to find another way to achieve it. – tolerate_Me_Thx Jan 04 '18 at 07:36

1 Answers1

0

Try setting the tableView's contentOffset to the tableView's contentSize, i.e.

override func viewDidAppear(_ animated: Bool)
{
    super.viewDidAppear(animated)
    let bottomOffSet = CGPoint(x: 0, y: self.tableView.contentSize.height - self.tableView.bounds.size.height)
    self.tableView.setContentOffset(bottomOffSet, animated: false)
}

Set the contentOffset in viewDidAppear.

Also implement the following UITableViewDelegate methods:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
    return UITableViewAutomaticDimension
}

override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat
{
    return 126.0 //Maximum possible cell height
}
PGDev
  • 23,751
  • 6
  • 34
  • 88