I have a UITableView with a cell that is dynamically sized to fit a UITextView inside it. Whenever a key is typed, the cell checks to see if the calculated height has increased,
More simplified solution (add Notification observer when textView is changed), Swift-version. Main trick is using UIView.setAnimationsEnabled
.
func textViewDidChanged(notification: NSNotification) {
UIView.setAnimationsEnabled(false)
let contentOffset = self.tableView.contentOffset
tableView.beginUpdates()
tableView.endUpdates()
tableView.contentOffset = contentOffset
UIView.setAnimationsEnabled(true)
}
Here is my UITableView extension that works perfectly. In Swift 2.1. Based on the accepted answer.
extension UITableView
{
func reloadDataAnimatedKeepingOffset()
{
let offset = contentOffset
UIView.setAnimationsEnabled(false)
beginUpdates()
endUpdates()
UIView.setAnimationsEnabled(true)
layoutIfNeeded()
contentOffset = offset
}
}
Just a guess...
Save the contentOffset
of the uitableview before any changes. Then set it again after.
CGFloat contentOffset = self.tableView.contentOffset;
and then after the changes
self.tableView.contentOffset = contentOffset;
Wow, Josh Gafni's answer helped a lot; he deserves an upvote. My solution is based off his. This still feels like a hack, so if anyone still has a better way to do this, I'm still very interested to hear it.
First I save the content offset, then I start the update.
CGPoint offset = self.tableView.contentOffset;
[self.tableView beginUpdates];
[self.tableView endUpdates];
This animates the cell's height change and adjusts all the frames to suit the constraints.
Next I remove all animations from the tableView's layer, so the animation to the top stops. Then I reset the contentOffst to what it was before.
[self.tableView.layer removeAllAnimations];
[self.tableView setContentOffset:offset animated:NO];
Finally, I let the tableView handle the animated scroll down so the bottom of the cell is right above the keyboard.
[self.tableView scrollToRowAtIndexPath:CreateNoteCellIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
And voila, it works pretty well.