tl; dr状态恢复过程似乎正在发生,但堆栈(非根)视图控制器在恢复完成后不会在应用程序中结束。
我正在尝试在应用中实现状态恢复,该应用不使用任何.nib或故事板。这是一个相当基本的结构:窗口的rootViewController
是UINavigationController
,其rootViewController
和所有其他子视图控制器都是UITableViewControllers
(例如,Window> Nav Ctrl> Table查看Ctrl>表视图Ctrl>等)。没有任何视图控制器被重复(即堆栈中的每个项目都是不同的UITableViewController
子类)
由于我没有使用故事板创建视图控制器,因此我为每个视图控制器类设置了指定的初始化程序,设置了restorationIdentifier
和restorationClass
。
当应用程序正在恢复时,我看到当应用程序进入后台时存在的每个视图控制器发生解码(例如,导航控制器,播客列表控制器和播客详细控制器),但是恢复的最终结果始终是导航控制器显示正常的根视图控制器(播客列表控制器)。
问题似乎非常相似to this question,但我肯定在我的视图控制器(如果存在)上的super
- 和encode
方法中调用decodeRestorableStateWithCoder:
,以便解决方案对我没有帮助。
我观看了WWDC视频并经历了许多教程,虽然我似乎达到了所有要求,但事情并没有按照应有的方式发挥作用。
我能想到的唯一事情是恢复正在发生,但我的默认初始化代码正在用仅包含根的“新鲜”替换已恢复的导航视图控制器堆栈。根据WWDC视频,窗口和根视图控制器应该在状态恢复之前正常设置,这不应该影响恢复后的最终应用程序状态。
我想我的一个问号是我的viewControllerWithRestorationIdentifierPath:
的{{1}}方法实际应该发生什么。我应该像我一样设置UINavigationController
吗?如果没有,还会发生什么?我实际上找不到任何正在恢复导航控制器的工作示例代码,而且它不是从笔尖或故事板创建的。除此之外,我很难过。
rootViewController
# pragma mark - UIApplicationDelegate
# pragma mark Monitoring App State Changes
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Window and root VC set up in window getter
[self.window makeKeyAndVisible];
return YES;
}
# pragma mark Managing App State Restoration
- (BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder {
return YES;
}
- (BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder {
return YES;
}
#pragma mark Providing a Window for Storyboarding
- (UIWindow *)window {
if (!_window) {
_window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
_window.rootViewController = self.navigationController;
}
return _window;
}
- (FLNavigationController *)navigationController {
if (!_navigationController) {
FLPodcastTableViewController* podcastViewController = [[FLPodcastTableViewController alloc] initWithStyle:UITableViewStylePlain];
_navigationController = [[FLNavigationController alloc] initWithRootViewController:podcastViewController];
}
return _navigationController;
}
- (id)initWithRootViewController:(UIViewController *)rootViewController {
self = [super initWithRootViewController:rootViewController];
if (self) {
self.restorationIdentifier = @"FLNavigationController";
self.restorationClass = self.class;
}
return self;
}
#pragma mark - UIViewControllerRestoration
+ (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder {
FLPodcastTableViewController* podcastViewController = [[FLPodcastTableViewController alloc] initWithStyle:UITableViewStylePlain];
return [[self alloc] initWithRootViewController:podcastViewController];
}
- (id)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
[self.tableView registerClass:FLPodcastTableViewCell.class forCellReuseIdentifier:FLPodcastTableViewCellIdentifier];
self.restorationIdentifier = @"FLPodcastTableViewController";
self.restorationClass = self.class;
}
return self;
}
#pragma mark - UIViewControllerRestoration
+ (UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder {
return [[self alloc] initWithStyle:UITableViewStylePlain];
}