iphone - iOS 6 - 状态保存和恢复

标签 iphone xcode cocoa-touch ios6 uikit-state-preservation

我已经实现了 iOS 6 API 来保存状态,它可以工作 - 在我退出应用程序并重新启动几毫秒后,恢复的 View Controller 飞入,但随后它被我在启动时显示的主视图 Controller 取代。

每次应用启动主窗口的 Root View 时我都会进行设置,所以这一定是问题所在。

这是我的代码:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self commonInitializationLaunching:launchOptions];
    return YES;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self commonInitializationLaunching:launchOptions];
    return YES;
}

- (void)commonInitializationLaunching:(NSDictionary *)launchOptions
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        static NSString *const kKeychainItemName = @"OAuthGoogleReader";
        self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
        self.navController = [[UINavigationController alloc] initWithRootViewController:self.viewController];

        GTMOAuth2Authentication *auth;
        auth = [GTMOAuth2ViewControllerTouch authForGoogleFromKeychainForName:kKeychainItemName
                                                                     clientID:kClientID
                                                                 clientSecret:kClientSecret];

        self.window.rootViewController = self.navController;

        [self.window makeKeyAndVisible];

        BOOL isSignedIn = [auth canAuthorize];
        if (isSignedIn) {
            NSLog(@"Signed");
        }else{
            NSString *scope = @"https://www.google.com/reader/api/";

            GTMOAuth2ViewControllerTouch *viewController;
            viewController = [[GTMOAuth2ViewControllerTouch alloc] initWithScope:scope
                                                                        clientID:kClientID
                                                                    clientSecret:kClientSecret
                                                                keychainItemName:kKeychainItemName
                                                                        delegate:self
                                                                finishedSelector:@selector(viewController:finishedWithAuth:error:)];
            [self.navController pushViewController:viewController animated:YES];
            //        self.window.rootViewController = viewController;
        }
    });
}

你可以在 -(void)commonInitializationLaunching:(NSDictionary *)launchOptions 中看到这一点 我正在设置窗口的 Root View 。我不知道该放什么进去。也许检查是否有保存的状态然后加载这个方法?但如何呢?

谢谢!

以下是我按照 Rob 的建议尝试过的方法:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    if (!self.isRestored) {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    }
    [self commonInitializationLaunching:launchOptions];
    [self.window makeKeyAndVisible];
    return YES;
}

willFinishLaunching 中没有任何内容... 我还通过窗口代码从我的 commonInitializationLaunching 方法中删除了。

最佳答案

Storyboard将为您完成大部分繁重的工作,例如恢复窗口。但是,使用代码不会恢复窗口。您需要使用编码器来保留 Root View Controller 。您的代码将如下所示:

NSString * const AppDelegateRootVCKey = @"AppDelegateRootVCKey";

- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder {
    [coder encodeObject:self.window.rootViewController forKey:AppDelegateRootVCKey];
}

- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder {

    // Grabs the preserved root view controller.
    UIViewController * vc = [coder decodeObjectForKey:AppDelegateRootVCKey];

    if (vc) {
        UIWindow * window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        window.rootViewController = vc;
        window.restorationIdentifier = NSStringFromClass([window class]);

        // The green color is just to make it obvious if our view didn't load properly.
        // It can be removed when you are finished debugging.
        window.backgroundColor = [UIColor greenColor];

        self.window = window;
    }
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if (!self.window) {

        UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

        // The blue color is just to make it obvious if our view didn't load properly.
        // It can be removed when you are finished debugging.
        window.backgroundColor = [UIColor blueColor];

        UIViewController *root = // However you create your root.

        window.rootViewController = root;
        window.restorationIdentifier = NSStringFromClass([window class]);

        self.window = window;
    }

    [self commonInitializationLaunching:launchOptions];
    [self.window makeKeyAndVisible];

    return YES;
}

另一个需要注意的问题是确保您的 UINavigationController 和 UITabBarController 具有恢复标识符。

关于iphone - iOS 6 - 状态保存和恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12567570/

相关文章:

iphone - 仅使用 iPhone 顶部的麦克风

iphone - 如何在未加入 iPhone Developer Program 的情况下在越狱的 iPhone 上构建和安装应用程序?

iphone - Objective-C 代码中未找到 windowScriptObject 方法

ios - AVPlayerItem 初始 timedMetadata 未被观察(KVO)

ios - 用户键入新行时如何向 UITextView 添加自动缩进?

iphone - UITextView 中的合理对齐 - iPhone

iphone - 可以在App Store中停止可用性,但继续为其提供最新更新吗?

iphone - 在 cocos2d 游戏中重播关卡以防止终止的正确方法是什么?

swift - Swift 4 中的日期/时间选择器

ios - Cordova-plugin-firebase : Cannot run on iOS 12. 2 但在 android 和 iOS 10.3.3 上运行没有任何问题