I have an app that is using UIKit state preservation in iOS 6. I am able to save/restore the state of the view controllers, ie which tab is selected and navigation controller hierarchy, however I cannot get my table view to restore it's offset. I have a restoration identifier in my storyboard for the view as well as the view controller and the view controller (the table's data source) implements UIDataSourceModelAssociation
as follows:
- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)indexPath inView:(UIView *)view
{
TSStatus *status = [self._fetchedResultsController objectAtIndexPath:indexPath];
return status.objectID.URIRepresentation.absoluteString;
}
- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view
{
NSURL *statusURL = [NSURL URLWithString:identifier];
NSManagedObjectID *statusID = [[TSDataController sharedController].persistentStoreCoordinator managedObjectIDForURIRepresentation:statusURL];
TSStatus *status = (TSStatus *)[[TSDataController sharedController].mainContext objectWithID:statusID];
return [__fetchedResultsController indexPathForObject:status];
}
modelIdentifierForElementAtIndexPath:inView:
is getting called when the app goes into the background, however modelIdentifierForElementAtIndexPath:inView:
never gets called.
This isn't a real answer to your question, but I've not been able to get a table view restore its contentOffset, either.
I guess this is a bug in iOS 6, because the documentation clearly states that a UITableView
restores its contentOffset, when 1) it has a restorationIdentifier
2) the view controller the view belongs to has a restorationIdentifier
and 3) the data source conforms to the UIDataSourceModelAssociation
protocol.
You can restore the contentOffset and the selected item manually in your view controller, though:
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
[super encodeRestorableStateWithCoder:coder];
[coder encodeObject:[NSValue valueWithCGPoint:self.tableView.contentOffset] forKey:@"tableView.contentOffset"];
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
if (indexPath != nil) {
NSString *modelIdentifier = [self modelIdentifierForElementAtIndexPath:indexPath inView:self.tableView];
[coder encodeObject:modelIdentifier forKey:@"tableView.selectedModelIdentifier"];
}
}
- (void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
[super decodeRestorableStateWithCoder:coder];
CGPoint contentOffset = [[coder decodeObjectForKey:@"tableView.contentOffset"] CGPointValue];
self.tableView.contentOffset = contentOffset;
NSString *modelIdentifier = [coder decodeObjectForKey:@"tableView.selectedModelIdentifier"];
if (modelIdentifier != nil) {
NSIndexPath *indexPath = [self indexPathForElementWithModelIdentifier:modelIdentifier inView:self.tableView];
if (indexPath != nil) {
[self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}
}
I have no idea why UITableView
doesn't do that automatically, even though the documentation says it does. If someone knows the answer, please comment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With