UIViewController состояние восстановления без раскадровки не работает

Я хотел бы реализовать сохранение состояния и восстановление в моем приложении для iOS 6, которое не использует раскадровки. Мой основной контроллер вида, который я хочу сохранить и восстановить состояние, - это UIViewController, который является частью UINavigationController.

Мой контроллер представления расширяет протокол UIViewControllerRestoration. Я думаю, что я реализую все необходимые методы, но я не вижу каких-либо вызовов для encodeRestorableStateWithCoder или decodeRestorableStateWithCoder из симулятора.

Вот как выглядит мой делегат приложения: MyAppDelegate:

- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder {
    NSLog(@"shouldSaveApplicationState"); // seeing this in the debug window
    return YES;
}

- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder {
    NSLog(@"shouldRestoreApplicationState"); // seeing this in the debug window
    return YES;
}

- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder {
    NSLog(@"willEncodeRestorableStateWithCoder"); // seeing this in the debug window
}

- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder {
    NSLog(@"didDecodeRestorableStateWithCoder"); // seeing this in the debug window
}

Я вижу все эти вызовы в окне отладки. Вот как выглядит мой MyMainViewController, который отображается в режиме ожидания приложения:

@interface MyMainViewController : UIViewController <UIViewControllerRestoration>
@end

@implementation MyMainViewController

- (id)init {
    if (self = [super init]) {
        self.restorationIdentifier = @"MyViewControllerRestoreId";
        self.restorationClass = [self class];
    }
    return self;
}

- (void)loadView {
    self.view = [[UIView alloc] initWithFrame:frame];

    // Bunch of work to create my custom views
}

- (void)awakeFromNib {
    self.restorationClass = [self class];
}

// Expected a call to this method, but not seeing it in debug window
+ (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents
                                                            coder:(NSCoder *)coder {
    NSLog(@"viewControllerWithRestorationIdentifierPath: %@", identifierComponents);

    MyMainViewController *vc = [[MyMainViewController alloc] init];
    vc.restorationIdentifier = [identifierComponents lastObject];
    vc.restorationClass = [MyMainViewController class];

    return vc;
}

// Expected a call to this method, but not seeing it in debug window    
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder {
    NSLog(@"encodeRestorableStateWithCoder");
    [super encodeRestorableStateWithCoder:coder];
}

// Expected a call to this method, but not seeing it in debug window    
- (void)decodeRestorableStateWithCoder:(NSCoder *)coder {
    NSLog(@"decodeRestorableStateWithCoder");
    [super decodeRestorableStateWithCoder:coder];
}    
@end

Как я использую симулятор для проверки сохранения и восстановления:

1. Launch app in Simulator via Xcode
2. Invoke the Home key so App is now suspended. This where I see:
    shouldSaveApplicationState  
    willEncodeRestorableStateWithCoder
3. End the debugging session in XCode (Command .)
4. Start a new debug session of the app in XCode. I see:
    shouldRestoreApplicationState
    didDecodeRestorableStateWithCoder

Я не уверен, что еще мне не хватает, чтобы сделать эту работу.

3 ответа

У меня была точно такая же проблема. Оказалось, мне нужно было явно установить протокол на контроллере представления, чтобы использовать recoveryClass:

<UIViewControllerRestoration>

Похоже, вы уже сделали, но в итоге это сделали для меня.

Этот код может не работать:

- (id)init {
    if (self = [super init]) {
        self.restorationIdentifier = @"MyViewControllerRestoreId";
        self.restorationClass = [self class];
    }
    return self;
}

Назначенный инициализатор для контроллера представления initWithNibName:bundle:так что нет никаких гарантий, что его init когда-либо называется. Кроме того, если контроллер представления исходит от xib или раскадровки, ни один из этих методов никогда не вызывается.

У вас есть awakeFromNib реализация:

- (void)awakeFromNib {
    self.restorationClass = [self class];
}

Это будет работать, если контроллер представления исходит от XIB или раскадровки, но тогда в этом случае вы забыли назначить restorationID,

Не знаю, поможет ли это или что-то изменит, поскольку я сам только изучаю сохранение / восстановление состояния, но вот кое-что, что вы можете попробовать, я получил из учебника, над которым я работаю.

Если ваш VC находится в TabBar или NavController, удостоверьтесь, что у них также есть recoveryIdentifier.

Другие вопросы по тегам