reloadData() of UITableView with Dynamic cell heights causes jumpy scrolling reloadData() of UITableView with Dynamic cell heights causes jumpy scrolling swift swift

reloadData() of UITableView with Dynamic cell heights causes jumpy scrolling


To prevent jumping you should save heights of cells when they loads and give exact value in tableView:estimatedHeightForRowAtIndexPath:

Swift:

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 {    return cellHeights[indexPath] ?? UITableView.automaticDimension}

Objective C:

// declare cellHeightsDictionaryNSMutableDictionary *cellHeightsDictionary = @{}.mutableCopy;// declare table dynamic row height and create correct constraints in cellstableView.rowHeight = UITableViewAutomaticDimension;// save height- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {    [cellHeightsDictionary setObject:@(cell.frame.size.height) forKey:indexPath];}// give exact height value- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {    NSNumber *height = [cellHeightsDictionary objectForKey:indexPath];    if (height) return height.doubleValue;    return UITableViewAutomaticDimension;}


Swift 3 version of accepted answer.

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 {    return cellHeights[indexPath] ?? 70.0 }


The jump is because of a bad estimated height. The more the estimatedRowHeight differs from the actual height the more the table may jump when it is reloaded especially the further down it has been scrolled. This is because the table's estimated size radically differs from its actual size, forcing the table to adjust its content size and offset.So the estimated height shouldn't be a random value but close to what you think the height is going to be. I have also experienced when i set UITableViewAutomaticDimensionif your cells are same type then

func viewDidLoad() {     super.viewDidLoad()     tableView.estimatedRowHeight = 100//close to your cell height}

if you have variety of cells in different sections then I think the better place is

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {     //return different sizes for different cells if you need to     return 100}