How to prevent from scrolling UITableView up when NSFetchedResultsController add new record?
Edited answer:
I was able to reproduce this glitch with the following steps:
UITableView
with itsrowHeight
set toUITableViewAutomaticDimension
and non-zeroestimatedRowHeight
.- Table scrolled to its very bottom, with the last cell fully visible at the bottom margin.
- Inserting the new cell below the last one results in visual shift of the cells a few points down (in my setup it differs from 5 to 40).
The source of this behavior needs additional investigation.
For now the only solution is not to use UITableViewAutomaticDimension
and return row heights from tableView:heightForRowAtIndexPath:
.
By the way, implementation of inverted index paths has one significant flaw. When FRC calls it's delegate method controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
, all deletion index paths belongs to pre-change data set, and all insertion index paths - to post-change one. When you are in-beetween controllerWillChangeContent:
and controllerDidChangeContent:
, fetchedResultsController.fetchedObjects
will contain post-change data set, i suppose (needs to be checked, though).
NSFetchedResultsController and scrollToBottom in Table
Don't scroll, just set the content offset without animation. At minimum the height of each cell needs to be determined but the cell itself doesn't need to be loaded for every row.
Note that most apps which display in this way won't have all old messages in the immediate history, they'll only have a couple of pages, and if you scroll up too far they'll need to go and load those older messages. This approach bounds and loading issues.
Make UITableView keep scroll position when adding cells at top
Ok, after some responses which pointed me in right direction I came up with this solution. It works smooth though does some ugly coordinates math and doesn't support different cell sizes. Hope it will be helpful for someone.
-(void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
NSIndexPath *firstVisible = [[self.tableView indexPathsForVisibleRows] firstObject];
self.topVisibleMessage = [self.fetchedResultsController objectAtIndexPath:firstVisible];
NSIndexPath *topIndexPath = [self.fetchedResultsController indexPathForObject:self.topVisibleMessage];
self.cellOffset = self.tableView.contentOffset.y - topIndexPath.row * [self firstRowHeight];
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView reloadData];
if (self.topVisibleMessage) {
NSIndexPath *topIndexPath = [self.fetchedResultsController indexPathForObject:self.topVisibleMessage];
CGPoint point = {0, topIndexPath.row * [self firstRowHeight] + self.cellOffset};
[self.tableView setContentOffset:point];
}
}
Issues when inserting multiple rows into a tableView using NSFetchedResultsController delegate methods
Since my cell heights are dynamic, I was setting the estimatedRowHeight
to 300, changing it to 1000 seemed to fix my problem. If you know of any other way to fix it besides this, or any improvement to my code, let me know. Thanks
This is what lead me to my answer.
https://stackoverflow.com/a/38867302/4745553
EDIT
I actually was still having an issue and since I was responding to multiple changes, I was just using the controllerDidChangeContent
delegate method and called tableView.reloadData()
in their. Their is no animation but that's okay with what I'm doing.
This helped me fix it as well. https://stackoverflow.com/a/3013353/4745553
Related Topics
How to Use Sfsafariviewcontroller with Swiftui
Writing an iOS 8 Share Extension Without a Storyboard
Html5 Video Autoplay on Iphone
<Input Type="Number"/> Is Not Showing a Number Keypad on iOS
Scrolling Slow on Mobile/iOS When Using Overflow:Scroll
iPhone 6 and 6 Plus Responsive Breakpoints
While Scrolling on an iOS Device, the Z-Index of Elements Isn't Working
iPhone iOS Will Not Display Box-Shadow Properly
Mobile Safari Position:Fixed Z-Index Glitch When Scrolling
Webkit Overflow Scrolling Touch CSS Bug on iPad
iOS Safari Memory Usage with "-Webkit-Transform"
CSS Gradient Not Working on iOS
Div Scrolling Freezes Sometimes If I Use -Webkit-Overflow-Scrolling
Wkwebview Fails to Load Images and CSS Using Loadhtmlstring(_, Baseurl:)