UITableView jumpy on scroll after changing cell he

2019-04-10 00:38发布

问题:

So I have a tableView where I want to change the height of a cell when tapped. Well, actually, I am replacing it with a bigger cell. On tap, I call:

tableView.beginUpdates()
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
tableView.endUpdate()

And then I modify my cellForRowAtIndexPath to return the right new cell and height. The cell's height is being automatically calculated by overriding sizeThatFits in the cell's implementation:

override func sizeThatFits(size: CGSize) -> CGSize {
    return CGSizeMake(size.width, myHeight)
}

Oddly enough, after I do this, scrolling downwards is fine, but when I scroll upwards, the table jumps 5 or so pixels every second until I reach the top. After I reach the top of the table, the problem is gone and there is no jumping going in either direction. Any idea why this is happening? I imagine it has something to do with the new cell height displacing the other cells, but I can't see why the tableView is not taking care of this. Any help is appreciated!

Thanks!

EDIT: Added code from cellForRowAtIndexPath:

 if self.openedCellIndex != nil && self.openedCellIndex == indexPath {
     cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as ListCell
     (cell as ListCell).updateWithDetailView(dayViewController!.view)
 } else {
     cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as ListCell
     (cell as ListCell).updateWithData(eventDay: store.events![indexPath.row], reminderDay: store.reminders![indexPath.row])
 }
 return cell

回答1:

You should include your code for cellForRow and heightForRow, but I will give it a blind shot.

When a cell is tapped in cellForRow you should store the index of that cell, then reload the data or just that cell. Then in heightForRow use if(yourTappedCell){return preferredHeight;}



回答2:

Unfortunately, there does not seem to be a simple answer to this. I have struggled with it on multiple iOS apps.

The only solution I have found is to programmatically scroll to the top of your UITableView once it appears again.

[self.tableView setContentOffset:CGPointMake(0, 0 - self.tableView.contentInset.top) animated:YES];

OR

self.tableView.contentOffset = CGPointMake(0, 0 - self.tableView.contentInset.top);

Hope this an acceptable work around while still being able to use dynamic cell heights =)