2013-07-18 9 views
9

Mi piacerebbe fare il ripristino dello stato nella mia app che non usa le storyboard. Vedo che la mia app principale ViewController è stata istanziata due volte durante il ripristino dello stato: come ci si assicura che venga creata una sola volta?Modo corretto per creare e ripristinare UIViewControllers durante il ripristino dello stato?

Il modo comprendo il flusso, application:willFinishLaunchingWithOptions e pplication:didFinishLaunchingWithOptions potrebbe usare un metodo commonInit che avrebbero impostare le applicazioni UIWindow e la sua RootViewController. Nel mio caso, rootViewController è un UINavigationController con una classe denominata "MyMainViewController" che funge da rootViewController di UINavigation.

Accanto a questo sto gestendo anche willEncodeRestorableStateWithCoder e didDecodeRestorableStateWithCoder, rispettivamente. Ma sembra che nel momento in cui arrivo al mio didDecodeRestorableStateWithCoder, vedo due istanze separate di MyMainViewController create.

Qual è il modo per garantire che venga creato un solo UIViewController durante il ripristino?

Ordine di chiamate durante il restauro:

  • Crea nuovo MyMainViewController istanza (# 1) tramite applicazione: willFinishLaunchingWithOptions:
  • di MyMainViewController viewControllerWithRestorationIdentifierPath: codificatore invocato e MainViewController viene ripristinata (# 2)
  • applicazione : didDecodeRestorableStateWithCoder: viene chiamato e UINavigationController viene decodificato e assegnato a self.window

Ecco quello che sto facendo nel mio AppDelegate:

NSString * const kRootViewControllerKey = @"RootViewControllerKey"; 

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

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

- (void)commonInitWithOptions:(NSDictionary *)launchOptions { 

    static dispatch_once_t predicate; 
    dispatch_once(&predicate,^{ 

     // While this will be called only once during the lifetype of the app, when the process is killed 
     // and restarted, I wind up with an instance of MyMainViewController created first from here 
     // and then once again, during MyMainViewController's viewControllerWithRestorationIdentifierPath:coder 
     // that's invoked later on. 

     UIViewController *rootViewController = [MyMainViewController alloc] init]; 
     UINavigationController *aNavController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; 

     aNavController.navigationBarHidden = YES; 
     aNavController.restorationIdentifier = NSStringFromClass([aNavController class]); 

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

     self.window = aWindow; 
    }); 
} 

// Encode app delegate level state restoration data 
- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder { 
    [coder encodeObject:self.window.rootViewController forKey:kRootViewControllerKey]; 
} 

// Decode app delegate level state restoration data 
- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder { 

    // Find the preserved root view controller and restore with it 
    UINavigationController *navControlller = [coder decodeObjectForKey:kRootViewControllerKey]; 

    if (navControlller) { 
     self.window.rootViewController = navControlller; 
    } 

} 
+0

hai mai trovato una soluzione per questo? Sto correndo nello stesso identico problema, vedendo che il mio controller di visualizzazione è stato avviato due volte. – djibouti33

+0

No, mai fatto. Non sono sicuro su come aggirare il problema perché non posso passare all'utilizzo degli storyboard. –

risposta

0

C'è sempre e solo doveva essere un'istanza della mia classe di visualizzazione radice, quindi ho risolto con l'aggiunta di un metodo di classe per alloc e init della classe solo una volta e restituire il valore altrimenti:

+ (id) initOnce { 
    static id view_ref; 

    if(!view_ref) 
     view_ref = [[UIViewController alloc] init]; 

    return view_ref; 
} 

Ora, quando la classe viene inizializzato tramite [UIViewController initOnce], sempre ottiene rinviato lo stesso riferimento di vista, sia durante willFinishLaunchingWithOptions o viewControllerWithRestorationIdentifierPath.

+0

Inoltre, non puoi semplicemente impostare .restorationClass nella vista root e il ripristino dello stato UIKit sembra fare "The Right Thing". – jasonjwwilliams

Problemi correlati