Dev*_*fly 11 iphone xcode cocoa-touch ios6 uikit-state-preservation
我已经实现了用于状态保存的iOS 6 API,它可以工作 - 在我退出应用程序并重新启动几毫秒后,恢复的视图控制器会进入,但随后它被我在启动时显示的主视图控制器所取代.
每次应用程序启动主窗口的根视图时我都会设置,所以这一定是问题所在.
这是我的代码:
- (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;
}
});
}
Run Code Online (Sandbox Code Playgroud)
你可以看到 - (void)commonInitializationLaunching:(NSDictionary*)launchOptions我正在设置我的窗口的根视图.我不知道该放什么.也许检查是否有保存状态,然后加载此方法?但是怎么样?
谢谢!
以下是我根据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;
}
Run Code Online (Sandbox Code Playgroud)
什么都没有willFinishLaunching......我也从我的commonInitializationLaunching方法中删除了窗口代码.
rbr*_*own 24
故事板将为您完成大部分繁重工作,例如恢复窗口.但是,使用代码不会恢复窗口.您需要使用编码器保持根视图控制器.您的代码看起来像这样:
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;
}
Run Code Online (Sandbox Code Playgroud)
另外需要注意的是确保您的UINavigationControllers和UITabBarControllers具有恢复标识符.
状态恢复通常与故事板集成在一起.如果您正在使用故事板,则不应创建自己的窗口,查看控制器等.您应该让故事板为您执行此操作.发生的事情是故事板正在进行所有状态恢复,然后你正在创建一个新窗口并将其置于所有状态之上.如果是这种情况,您可能会在每次启动时创建两个UI副本.你只是没有注意到它.
如果您在代码中构建整个接口(不是推荐的方法,但它确实有效),那么您需要确定在创建UI之前是否发生了状态恢复.这很简单:
在您的commonInitializationLaunching:初始化中,仅初始化非UI元素(不会出现在状态保存中的事物).这是处理UI元素在状态恢复期间可能依赖的事物的地方.您当前的代码中没有任何这些.
在application:didDecodeRestorableState:,设置应用程序委托ivar以指示状态已恢复.
在application:didFinishLaunchingWithOptions:运行后commonInitializationLaunching:,请检查您的伊娃.如果未恢复状态,请创建UI.
请记住,该commonInitializationLaunching:模式仅用于向后兼容iOS 5.如果您不需要,则只需将非UI willFinish和UI放入didFinish(如果状态未恢复).
| 归档时间: |
|
| 查看次数: |
7641 次 |
| 最近记录: |