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.