3

それぞれ独自のナビゲーション コントローラーを持つ 2 つのタブを持つ UITabBarController を持つアプリケーションがあります。ここで、ユーザーがアプリケーションを閉じたときのアプリケーションの状態を保存して、ユーザーがアプリケーションを再起動したときに、アプリケーションが最後に閉じられる前と同じ場所を表示するようにします。
だから、アプリケーションでWillTerminate:私は持っています

[NSKeyedArchiver archiveRootObject:tabBarController toFile:@"lastVisitedTab"];

次に、アプリケーションでDidFinishLaunching: 私は持っています

UITabBarController *last= (UITabBarController *)[NSKeyedUnarchiver unarchiveObjectWithFile:@"lastVisitedTab"];
if (last)
    tabBarController = [last retain];

また、NSCoding に準拠させるための UIImage の拡張機能もあります。ただし、状態が保持されないため、これは機能しません。最初のタブが常に選択され、ナビゲーションも保持されません。
誰かが間違っていることを教えてくれますか、それとも正しく行う方法を教えてくれますか?

4

2 に答える 2

4

実際のオブジェクトを永続化するのはやり過ぎだと思います。代わりに、プロパティを保存してselectedIndex( を使用[NSNumber numberWithInt: tabBar.selectedIndex])、それを読み込んで、起動時にプロパティを設定します。これはあなたの質問に適切に答えないかもしれませんが、あなたが達成しようとしていることには十分かもしれません.

于 2009-10-13T09:44:45.103 に答える
2

Felixyzのアイデアのおかげで、最終的にそれを行う方法を見つけました。以下は、データに関係なく、タブを保存するために私がしなければならないことです。ビューが URL からダウンロードされたデータで読み込まれる場合は、ビュー全体ではなく URL を保存します。オーバーライドする必要があります

- (void)encodeWithCoder:(NSCoder *)encoder
- (id)initWithCoder:(NSCoder *)decoder

UIViewController サブクラスで、アプリケーションが停止する前に適切なデータを保存するようにビュー コントローラーに指示します。
アプリケーションデリゲートで、終了する前にデータを保存します

- (void)applicationWillTerminate:(UIApplication *)application
    // data buffer for archiving
    NSMutableData *data = [NSMutableData data];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    // the index of selected tab
    [archiver encodeInt:tabBarController.selectedIndex forKey:@"TAB_INDEX"];
    // array of keys for each navigation controller, here I have 3 navigation controllers
    NSArray *keys = [NSArray arrayWithObjects:
                     @"NAVIGATION_CONTROLLER_1",
                     @"NAVIGATION_CONTROLLER_2",
                     @"NAVIGATION_CONTROLLER_3", nil];
    for (int i = 0; i < keys.count; i++) {
        UINavigationController *controller = [tabBarController.viewControllers objectAtIndex:i];
        NSMutableArray *subControllers = [NSMutableArray arrayWithArray:controller.viewControllers];
        // the first view controller would already be on the view controller stack and should be removed
        [subControllers removeObjectAtIndex:0];
        // for each of the navigation controllers save its view controllers, except for the first one (root)
        [archiver encodeObject:subControllers forKey:[keys objectAtIndex:i]];
    }
    [archiver finishEncoding];
    // write that out to file
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    [data writeToFile:[documentsDirectory stringByAppendingPathComponent:@"ARCHIVE_PATH"] atomically:YES];
}

そして、再起動すると

- (void)applicationDidFinishLaunching:(UIApplication *)application {
    // set up the tabs
    tabBarController = [[UITabBarController alloc] init];
    tabBarController.viewControllers = [NSArray arrayWithObjects:
                                        [[[UINavigationController alloc] initWithRootViewController:rootViewController1] autorelease],
                                        [[[UINavigationController alloc] initWithRootViewController:rootViewController2] autorelease],
                                        [[[UINavigationController alloc] initWithRootViewController:rootViewController3] autorelease], nil];
    // look for saved data, if any
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSData *archive = [NSData dataWithContentsOfFile:[documentsDirectory stringByAppendingPathComponent:@"ARCHIVE_PATH"]];
    // if no data found, skip this step
    if (archive) {
        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:archive];
        // set the tab
        tabBarController.selectedIndex = [unarchiver decodeIntForKey:@"TAB_INDEX"];
        NSArray *keys = [NSArray arrayWithObjects:
                         @"NAVIGATION_CONTROLLER_1",
                         @"NAVIGATION_CONTROLLER_2",
                         @"NAVIGATION_CONTROLLER_3", nil];
        // push view controllers up the stack
        for (int i = 0; i < keys.count; i++) {
            NSArray *controllers = [unarchiver decodeObjectForKey:[keys objectAtIndex:i]];
            for (UIViewController *controller in controllers) {
                [((UINavigationController *)[tabBarController.viewControllers objectAtIndex:i]) pushViewController:controller animated:NO];
            }
        }
    }
    // Add the tab bar controller's current view as a subview of the window
    [window addSubview:tabBarController.view];
}
于 2009-10-15T07:41:45.017 に答える