UIViewController状态恢复没有故事板不工作

时间:2013-06-03 02:28:41

标签: ios ios6 uikit-state-preservation

我想在不使用故事板的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 个答案:

答案 0 :(得分:3)

我遇到了完全相同的问题。原来,我需要在视图控制器上显式设置协议,以便使用restorationClass:

<UIViewControllerRestoration>

好像你已经完成了,但最终还是为我做了。

答案 1 :(得分:1)

不知道这是否会有所帮助或有所作为,因为我自己只是在学习状态保存/恢复,但是我可以尝试从我正在研究的教程中获得这些内容。

如果你的VC在TabBar或NavController中,请确保他们也有一个restorationIdentifier。

答案 2 :(得分:1)

此代码可能未在运行:

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