Resize UITableView and keep scrolling from the bottom

I am trying to resize a table height using animation, it works fine by animating tableview frame.size.height.

The problem is that I have a table view of 200 pixels and it scrolls from the bottom, I want to animate it to 100 pixels, I run a simple

[UIView animateWithDuration:0.245f animations:^{ CGRect frame = tableview.frame; frame.size.height = 100.f; tableview.frame = frame; }]; 

this works fine, but after I resized it, it no longer scrolls to the bottom of the table. I want the tableview to always scroll down during the animation. I tried a lot of different things like calling

 [tablview scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

right before / after starting the resize animation, but I was not able to get them to sync 100%. Is there a way to resize the table while the last scroll element is displayed at the bottom of the table.

+6
source share
4 answers

I found a solution for my problem, there may well be a better solution, but actually it works very well :)

Before starting the animation, I see that contentSize.height is greater than the height of the target, if so I do the following:

 if (mMessages.contentSize.height > 150.f) { CGFloat expandedOffsetY = 52.f; CGFloat collapsedBottomOffset = (150.f + 18.f); CGFloat expandedBottomOffset = (MIN(320.f, mMessages.contentSize.height) + expandedOffsetY); tableFrame.origin.y = (collapsedBottomOffset - expandedBottomOffset) + expandedOffsetY; } else { tableFrame.origin.y = 18.f; tableFrame.size.height = 150.f; } 

this will cause the tableview to be presented in minus origin.y, then I wrapped the table in the β€œparent” uiview with clip signatures = YES.

Then I have a "completed" animation block that is "reset" to the target values.

 CGRect tableFrame = mMessages.frame; tableFrame.origin.y = 18.f; tableFrame.size.height = 150.f; mMessages.frame = tableFrame; if (mMessages.contentSize.height > tableFrame.size.height) { float contentOffsetY = mMessages.contentSize.height - tableFrame.size.height; mMessages.contentOffset = CGPointMake(0.0f, contentOffsetY); } 
+2
source

Try updating the contentOffset of the table view when animating the frame.

 [UIView animateWithDuration:0.245f animations:^{ CGRect frame = tableview.frame; frame.size.height = 100.f; tableview.frame = frame; float contentOffsetY = tableview.contentSize - tableview.frame.size.height; tableview.contentOffset = CGPointMake(0, contentOffsetY); }]; 
0
source
 [UIView animateWithDuration:0.245f animations:^{ CGRect frame = tableview.frame; frame.size.height = 100.f; tableview.frame = frame; } completion:^(BOOL finished) { // Find your last indexpath [tablview scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; } ]; 
0
source

Scrolling the table at the bottom of the animation block worked for me with one small twist: when I reduced the height of the View table, I called scrollToIndexPath without animation, and when I expanded the tableView, I called scrollToIndexPath with animation.

 UIView.animate(withDuration: 0.25) { [weak self] in guard let strongSelf = self else { return } // ... // updateConstraints // ... strongSelf.view.layoutIfNeeded() if reduceSize { tableView.scrollToLastRow(animated: false) } else { tableView.scrollToLastRow(animated: true) } } 

Extension for UITableView

 extension UITableView { func scrollToLastRow(animated: Bool) { let lastSection = numberOfSections-1 let lastRow = numberOfRows(inSection: lastSection)-1 let lastIndexPath = IndexPath(row: lastRow, section: lastSection) scrollToRow(at: lastIndexPath, at: .bottom, animated: animated) } } 
0
source

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


All Articles