1

設定

スライド メニューのカスタム コンテナー ビュー コントローラー ( MMDrawerController ) を使用して、中央のビュー コントローラーとスライド アウトの左メニュー/ドロワーを制御しています。Facebook アプリや他の何百ものアプリと同じように。

左側の引き出しを開いてメニュー項目をタップすると、中央のビュー コントローラーが置き換えられます。

機能しているもの

アプリを開いて最初の中央ビュー コントローラーのボタンを押すと (背景色が変更されます)、アプリを強制終了して背景色を正常に復元できます。完全。

機能していないもの

ロードする別のセンター VC を選択して (メニュー/ドロワーを開いてメニュー オプションを選択することにより)、アプリを強制終了すると、アプリはそのビュー コントローラーに復元されません。

私がやっていること

私の親View Controllerでは、左と中央のView Controllerをエンコードしているので、復元時にそれらを再作成できます。

- (void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
    [coder encodeObject:self.centerViewController forKey:@"centerVC"];
    [coder encodeObject:self.leftDrawerViewController forKey:@"leftDrawerVC"];
    [super encodeRestorableStateWithCoder:coder];
}

- (void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
    // if I don't change the center view controller, these values
    // get logged out as expected
    NSLog(@"leftDrawer: %@", [coder decodeObjectForKey:@"leftDrawerVC"]);
    NSLog(@"center: %@", [coder decodeObjectForKey:@"centerVC"]);
    [super decodeRestorableStateWithCoder:coder];
}

最初の中央のView Controllerの色を変更するフローでは、デコード中に中央と左のView Controllerを正常に戻すことができます。ただし、ロードする新しいセンター VC を選択するフローでは、これらのオブジェクトのデコード中に nil になります。

カスタム コンテナ ビュー コントローラをセットアップして、その子への参照を適切にエンコードし、デコード中にそれらを確実に取得できるようにするにはどうすればよいですか?

更新 1

適切に復元されないシナリオを実行した後、restoreArchiveTool を使用してアーカイブを調べました。実際、アーカイブには、予想されるエンコードされたオブジェクトの階層が含まれています。以前にエンコードされたView Controllerがデコード中にnullになる理由はまだわかりません。

更新 2この要点 のコメント セクションを見ると、保存と復元時にすべての適切なエンコード/デコード呼び出しが行われているように見えることがわかります。アプリのデリゲートで、最初にルート ビュー コントローラー (mmdrawercontroller のインスタンス) をセットアップしたときに、何らかの形で状態の復元を壊しているのだろうか? これが私がやっていることです:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UINavController *centerNav = [[UINavController alloc] initWithRootViewController:[FeaturedViewController new]];
    centerNav.restorationIdentifier = @"centerNav";
    UINavigationController *leftDrawerNavController = [[UINavigationController alloc] initWithRootViewController:[LeftDrawerViewController new]];
    leftDrawerNavController.restorationIdentifier = @"leftDrawerNav";

    MMDrawerController *drawerViewController = [[MMDrawerController alloc] initWithCenterViewController:centerNav leftDrawerViewController:leftDrawerNavController];

    // no restoration class, since this will always be created before state restoration resumes, and therefore will be found implicitly
    [drawerViewController setRestorationIdentifier:@"mmDrawer"];

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = drawerViewController;
    self.window.restorationIdentifier = NSStringFromClass([UIWindow class]);
    self.window.backgroundColor = [UIColor whiteColor];

    [self.window makeKeyAndVisible];
    return true;
}
4

1 に答える 1

1

私は MMDrawerController でも同様のことを行いましたが、問題は、UIKit が状態を復元しているときに、可能なすべての中央ビュー コントローラーを作成する方法を提供していないことだと思います。コントローラをエンコードすると、そのコントローラの復元 ID だけが保存されることに注意してください。アプリを次に起動したときに復元するには、UIKit がコントローラーのインスタンスを取得できる必要があります。それ自体は作成されません。次に示すように、インスタンスを取得するためにさまざまな方法が試行されます。

http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/StatePreservation/StatePreservation.html#//apple_ref/doc/uid/TP40007072-CH11-SW10

アプリは、(ストーリーボード経由または手動で) 毎回既定のセンター コントローラーを作成して、1 つが機能するようにすることができます。それ以外の場合は、おそらく復元クラスを実装するかapplication:viewControllerWithRestorationIdentifierPath:coder:、デリゲートに実装して、適切な型の新しいインスタンスを返す必要があります。

于 2013-08-01T05:15:50.293 に答える