Еще один вопрос о состоянии приложения iPhone - PullRequest
5 голосов
/ 07 апреля 2009

У меня есть еще один вопрос о восстановлении состояния приложения на iPhone. Простые данные (например, выбранная вкладка) могут храниться в NSUserDefaults, но этого недостаточно.

Я хочу восстановить все состояние, включая навигационные контроллеры (перейдите в суб-суб-суб-контроллер просмотра).

Моя проблема в том, что мое приложение разделено на несколько файлов xib, поэтому в начале не все экземпляры View Controllers создаются. Есть ли способ «форсировать» инстанцирование из xib-файла?

(у меня нет кода под рукой, но я могу попробовать написать небольшой конец, если он не понятен)

Большое спасибо.

Ответы [ 3 ]

5 голосов
/ 07 апреля 2009

Вызов [viewController view] обеспечит загрузку XIB данного контроллера вида; если это так, вы можете использовать любое из его других свойств в обычном режиме.

Вот что я склонен делать:

@class Record;  // some model object--I assume it has an integer record ID
@class DetailViewController;

@interface RootViewController : UIViewController {
    IBOutlet DetailViewController * detailController;
}

- (void)restore;
...
@end

@implementation RootViewController

// Note: all detailController showings--even ones from within 
// RootViewController--should go through this method.
- (void)showRecord:(Record*)record animated:(BOOL)animated {
    [self view];    // ensures detailController is loaded

    [[NSUserDefaults standardUserDefaults] setInteger:record.recordID 
                                               forKey:@"record"];
    detailController.record = record;

    [self.navigationController pushViewController:detailController 
                                         animated:animated];
}

- (void)restore {
    int recordID = [[NSUserDefaults standardUserDefaults] integerForKey:@"record"];

    if(recordID) {
        Record * record = [Record recordWithID:recordID];
        [rootViewController showRecord:record animated:NO];
        // If DetailViewController has its own state to restore, add this here:
        // [detailController restore];
    }
}
...
- (void)viewDidAppear:(BOOL)animated {
    [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"record"];
}
@end

@implementation MyAppDelegate

- (void)applicationDidFinishLaunching:(UIApplication*)application {
    ...
    [rootViewController restore];
    ...
}
...
@end

Каждый уровень иерархии представлений заботится о своем сохранении состояния, поэтому контроллеру приложения не нужно знать обо всех возможных представлениях и в каких порядках они могут быть.

4 голосов
/ 07 апреля 2009

Я делаю это в своем приложении, Litho Graph. Если при выходе вы находитесь на странице, то при следующем запуске она вернется на эту страницу. Это тоже довольно просто: в моей реализации -view контроллера -viewDidLoad я проверяю ключ последней просмотренной страницы по умолчанию. Если ничего нет, я продолжаю как обычно (и показываю список всех страниц). Если что-то есть, я открываю эту страницу (помещая новый контроллер представления в стек контроллера навигации).

Фактическая загрузка контроллеров представления очень проста: я просто создаю их экземпляр. Каждый из моих классов контроллеров представления имеет переопределенный параметр -init для вызова -initWithNibName: bundle: on super, поэтому для создания экземпляра контроллера представления достаточно вызвать + alloc и -init для загрузки его из соответствующего файла .xib. Затем, как описано выше, я помещаю его в стек контроллера навигации:

[self.navigationController pushViewController: controller animated: YES];

Конечно, вы можете сделать это на столько слоев, сколько вам нужно, но имейте в виду, что вы можете выдвигать контроллеры представления без анимации, если будет несколько переходов; пользователю было бы непродуктивно ждать нескольких анимаций (:

0 голосов
/ 18 ноября 2011

Посмотрите на пример кода «Развернуть». делает именно то, что вы хотите

...