8

iOS 6 で UIKit 状態保存を使用しているアプリがあります。View Controller の状態 (つまり、選択されているタブとナビゲーション コントローラー階層) を保存/復元できますが、テーブル ビューのオフセットを復元することはできません。ビューとビューコントローラーのストーリーボードに復元識別子があり、ビューコントローラー (テーブルのデータソース)UIDataSourceModelAssociationは次のように実装されています。

- (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:アプリがバックグラウンドに入るmodelIdentifierForElementAtIndexPath:inView:と呼び出されますが、呼び出されることはありません。

4

4 に答える 4

3

これはあなたの質問に対する本当の答えではありませんが、テーブル ビューで contentOffset を復元することもできませんでした。

これは iOS 6 のバグだと思います。ドキュメントには、aUITableViewが contentOffset を復元することが明確に記載さrestorationIdentifierれているrestorationIdentifierためUIDataSourceModelAssociationです。

ただし、ビュー コントローラーで contentOffset と選択した項目を手動で復元できます。

- (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];
        }
    }
}

ドキュメントにそう書いてあるのに、なぜUITableViewそれを自動的にしないのか、私にはわかりません。答えを知っている人は、コメントしてください。

于 2013-01-28T17:19:39.070 に答える
3

UITableViewにもrestoreIdentifierが設定されている場合、これが機能することがわかりました。

ただし、UITableViewController が UINavigationController 内にある場合は機能しません。これは、問題 ID: 13536778 として Apple に報告されています。この問題は、iOS 6.0 と 6.1.3 の両方で発生するようです。

于 2013-03-29T18:23:32.173 に答える
2

これは iOS 6 のバグです。

UIDataSourceModelAssociationプロトコルを使用してテーブル ビューの状態を復元するには、次のよう-reloadDataに有効なインデックス パスを返す前にテーブル ビューを呼び出す必要があります。-indexPathForElementWithModelIdentifier:inView:

- (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];

    [self.tableView reloadData];

    return [__fetchedResultsController indexPathForObject:status];
}
于 2013-05-05T20:01:22.837 に答える