2009-05-26 9 views
3

Also habe ich einen Stapel von drei UITableViewControllern, von denen jeder seine Sicht korrekt unter der Navigationsleiste anzeigt, wenn ich manuell durch die Benutzeroberfläche tappe.Layout verschraubt, wenn ich mehrere Controller ohne Animation stoße

Allerdings arbeite ich an der Wiederherstellung des Status über App-Neustart, und so schiebe ich die gleichen zwei Controller auf dem Root-View-Controller, einzeln, in der gleichen Methode im Haupt-Thread. Was dann passiert, ist, dass die Ansicht des mittleren Controllers zu weit nach unten gerichtet ist und die Ansicht des obersten Controllers zu weit oben ist (unterhalb der Navigationsleiste).

Relevante Code:

for (int i = 0; i < [controllerState count]-1; i++) { 
    MyViewController* top = (MyViewController*)navigationController.topViewController; 
    int key = [[controllerState objectAtIndex:i] integerValue]; 
    [top restoreNextViewController:key]; // this calls pushViewController: 
    // so top will be different in the next iteration 
} 

Ich vermute, dass das Problem ist, dass ich nicht einig wichtiger UI Refresh-Prozess stattfinden kann zwischen den beiden Schüben, weil sie im selben Thread passieren. Es sieht fast so aus, als ob die automatische Ansichtsanpassung, die den oberen Controller beeinflussen soll, stattdessen den mittleren beeinflusst.

Ist das richtig? Und wenn ja, was sollte ich tun, da ich möchte, dass die Wiederherstellung des Zustands sofort nach dem Start der App stattfindet?

EDIT: sieht aus wie ich war unklar. restoreNextViewController: ist eine MyViewController-Unterklassenmethode, die den Status des Controllers basierend auf einem gespeicherten Schlüssel wiederherstellt und dann den entsprechenden untergeordneten Controller mit [self.navigationController pushViewController:foo animated:NO] verschiebt. Ich mache das, weil meine eigentliche App, im Gegensatz zu diesem vereinfachten Fall, bis zu 6 Controller im Stack hat, und sie sind nicht immer die gleichen. Also dachte ich mir, das wäre ein saubereres Design, als den Stack runter zu gehen und die Klassen der Controller zu überprüfen. Jeder Controller weiß bereits, wie er als Reaktion auf Benutzereingaben einen Kindcontroller anstößt. Warum nicht das beim Neustart der App wiederverwenden?

Ich habe keine Probleme, die Controller zu zeigen; sie werden nur seltsam ausgelegt.

Antwort

0

Ich landete manuell zurückgesetzt jeden Inhalt der Tabellenansicht während seiner Controller viewWillAppear:.

0

Sie können pushViewController aufrufen: animiert: mehrere Male. Bitte geben Sie den Code für -restoreNextViewController ein. Es ist verwirrend, warum dieser Code so komplex ist wie er ist. Haben Sie den Abschnitt des View Controller Guide unter Creating a Nav Controller gelesen? Sie decken das Drücken von View-Controllern auf dem Stack beim Start ab.

+0

Ich habe keine Probleme, die Controller zu zeigen; Sie werden nur falsch ausgelegt. Siehe meine bearbeitete Frage. – lawrence

0

Ich stimme mit Rob überein, ich würde die Implementierung von UINavigationController betrachten, wenn Ihre Anwendung geladen wird. Dann würden Sie jeden Ihrer Controller auf UINavigtionController in der Reihenfolge schieben, in der Sie ihn überlagern möchten.

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated 

Also, wenn Sie wissen, in welchem ​​Zustand Sie Ihre Anwendung bringen wollen zurück zu Ihnen die entsprechenden Viewcontroller in der Reihe laden kann latered und schieben Sie sie auf die Navigation wird.

UIViewController *myViewController = [[UIViewController alloc] initWithNibName:@"myView" bundle:nil]; 
[navigationController pushViewController:myViewController animated:NO]; 

Dann, wenn Sie zurück in die UIViewController zu „Pop“ soll entweder der Benutzer die „Back“ kostenlos Taste auf navigationbar drücken. Oder Sie können die Navigation steuern mit

- (UIViewController *)popViewControllerAnimated:(BOOL)animated 

eg [[self navigationController] popViewControllerAnimated:NO]; 

können Sie auch festlegen, ob Sie die navigationbar wollen zeigen, oder nicht, wenn Sie die Push steuern möchten/Pop selbst. Ich hoffe, ich habe das gut genug erklärt. Ich bin gerade selbst diesen Weg gegangen.

1

Haben Sie darüber nachgedacht, dass jeder View-Controller während viewWillAppear: sein Kind drückt? Ich würde nur eine isRestoringState Eigenschaft in Ihrem AppDelegate setzen und überprüfen Sie, dass während viewWillAppear:, wenn es gesetzt ist, führen Sie Ihre Wiederherstellung für diese Ansicht, einschließlich Pushing alle sichtbaren untergeordneten Ansicht. Etwas wie:

- (void)viewWillAppear:(BOOL)animated { 
    if ([[UIApplication sharedApplication] isRestoringState]) { 
     // restore local state, set myChildController if a child is visible 
     if (myChildController) { 
      [self.navigationController pushViewController:myChildController animated:NO]; 
     } 
    } 
}