Cells fading during UITableView animation

I have a normal UITableView in my UIViewController limited to full screen. This tableView has a custom interactive tableHeaderView . TableHeaderView is dynamic in size and extends by itself. The header has a text filter and will change its own size depending on whether the textField object has focus or not.

The problem is that the cells at the bottom of the screen are not always animated correctly when resizing the HeaderView table. I call tableView.beginUpdates() and tableView.endUpdates() after layoutIfNeeded() inside my animation block. This must be done or the cells will not follow the dynamic size at all.

I made this gif. Look specifically at the bottom cells during the animation. I significantly slowed down the animation, so it's easy to see the problem.

gif problems

Speculation: It seems to me that the tableView calls cellForRow:indexPath: as soon as the animation starts, and somehow finds out what state the whole tableView will be after the animation, and deleting unnecessary cells, even if the animation is not completed yet. Similarly, when smoothing the header: the lowest cells do not animate in the same way as already loaded cells. They are animated with a different animation.

Why is this happening? Can this be prevented?

Edit: Animation code

 self.navigationController?.setNavigationBarHidden(isEditing, animated: true) var frame = tableHeaderView.frame frame.size.height = tableHeaderView.headerHeight(forEditing: isEditing) UIView.animate(withDuration: 0.3, animations: { if isEditing{ let point = CGPoint(x: 0, y: -self.topLayoutGuide.length) self.tableView.setContentOffset(point, animated: false) } tableHeaderView.frame = frame tableHeaderView.layoutIfNeeded() self.view.layoutIfNeeded() self.tableView.beginUpdates() self.tableView.endUpdates() }) { [weak self](completed:Bool) in //Do stuff } 
+5
source share
2 answers

Ok, I’ll try to offer my version, although I can’t check it, because I don’t see your project. I did not try to compile it, so it may have errors.

 var navFrame = self.navigationController?.navigationBar.frame navFrame.origin.y = isEditing ? -navFrame.size.height : 0 var frame = tableHeaderView.frame frame.size.height = tableHeaderView.headerHeight(forEditing: isEditing) UIView.animate(withDuration: 0.3, animations: { if isEditing{ let point = CGPoint(x: 0, y: -self.topLayoutGuide.length) self.tableView.contentOffset = point } self.navigationController?.navigationBar.frame = navFrame tableHeaderView.frame = frame self.view.layoutIfNeeded() }) { [weak self](completed:Bool) in //Do stuff } 
0
source

I just heard from the Apple Developer technical support team on this issue, and here is their answer verbatim (my emphasis):

Hi Nicholas

Thank you for contacting Apple Developer Technical Support (DTS).

The behavior and the resulting limitations that you describe are by design.

If you believe that Apple should consider an alternative approach, we recommend that you submit a promotion request with information on how this design decision affects you and what you like to see in different ways.

Although there are no promises that behavior will be changed, this is the best way to ensure that your thoughts on this matter are the team responsible for the decision.

Best wishes,

Apple Developer Technical Support

It seems we were just stuck in using a simple call to either tableView.setContentOffset(_:animated:) or tableView.scrollToRow(at:at:animated:) .

0
source

Source: https://habr.com/ru/post/1263566/


All Articles