Status Wiederherstellung in der Tab-Leiste und Navigation Controller App

8

Ziel: Ich versuche, den Status auf einer Tab-Controller-basierten App wiederherzustellen (mit Navigations-Controllern auf jeder Registerkarte).

Problem: Beim Relaunch scheint die ausgewählte Registerkarte erwartungsgemäß wiederhergestellt zu werden, aber die Navigationshierarchie in dieser Registerkarte ist nicht.

Entwicklung:

  1. Ich habe zuerst mit der Projektvorlage "Tab-basierte App" begonnen.
  2. Als Nächstes habe ich Wiederherstellungs-IDs sowohl für untergeordnete Ansichts-Controller als auch für den Tab-Leiste-Controller hinzugefügt.
  3. Im App-Delegaten habe ich application(_:shouldSaveApplicationState:) und application(_:shouldRestoreApplicationState:) .
  4. implementiert

Ich starte dann App, wechsle zum zweiten (rechten) Tab, drücke zu Hause, beende. o Neustart, die rechte Registerkarte wird angezeigt (wie erwartet). So weit so gut.

  1. Als Nächstes gehe ich zum Storyboard und bette beide Kinderansicht-Controller in die entsprechenden Navigations-Controller ein und weise ihnen auch Wiederherstellungs-IDs zu.

Ich starte die App und die Wiederherstellung funktioniert noch. Immer noch gut.

  1. Als nächstes füge ich einen "Detail" View Controller hinzu; Seine Klasse ist eine benutzerdefinierte Unterklasse von UIViewController für das Storyboard mit Eigenschaften zum Konfigurieren des Inhalts eines Debug-Labels und der Hintergrundfarbe seiner Ansicht.

  2. Ich habe einen "Show Detail ..." - Button auf jedem der Top-View-Controller der Registerkarten platziert und daraus jeweils einen Übergang in den (gemeinsamen) Detail-View-Controller erstellt. Jetzt sieht mein Storyboard wie ein Sechseck aus (außerdem haben beide Segmente IDs, die in Interface Builder festgelegt wurden). Daher teilen sich sowohl die linken als auch die rechten Controller der Draufsicht den gleichen Typ des "Detail" -Sichtkontrollers. Es wird so konfiguriert, dass es sich von der Stelle unterscheidet, an der es verschoben wurde (siehe nächster Punkt).

  3. Auf jeder der Methoden der top view controllers prepareForSegue(_:sender:) konfiguriere ich den Pushed Detail View Controller anders: Unterschiedliche Text- und Hintergrundfarbe ("left" und blau und "right" bzw. rot).

  4. Ich habe Code zum Detailansicht-Controller hinzugefügt, um den Status der Text- und Hintergrundfarbeneigenschaften zu speichern und wiederherzustellen: encodeRestorableStateWithCoder(_:) und decodeRestorableStateWithCoder(_:) . Außerdem habe ich viewDidLoad() implementiert, um die Werte dieser Eigenschaften in der Ansicht widerzuspiegeln. Wann immer es instanziiert und über ein Segment in die Navigation geschoben wird, werden zuerst die Eigenschaften festgelegt und dann verwendet, um die Ansicht in viewDidLoad() zu konfigurieren. Wenn sie bei der Wiederherstellung instanziiert werden, werden die Eigenschaften in decodeRestorableStateWithCoder(_:) und in ähnlicher Weise in viewDidLoad() festgelegt.

... aber wenn ich diesen Code ausführe, wird die zuletzt ausgewählte Registerkarte wiederhergestellt, aber nur bis zum Top-View-Controller - links oder rechts - nicht das Detail . Interessanterweise blinkt die Hintergrundfarbe, die zuletzt für den Detailansicht-Controller eingestellt wurde, für einen Augenblick.

Ich habe Haltepunkte in encodeRestorableStateWithCoder(_:) und decodeRestorableStateWithCoder(_:) platziert, aber nur die erste wird ausgeführt ( encode ).

  1. Ich habe mich gefragt, was vielleicht noch fehlt, und habe den% s application(_:viewControllerWithRestorationIdentifierPath:coder:) des Anwendungsdelegaten implementiert (wobei immer nil zurückgegeben wird, aber die übergebenen Pfadkomponenten protokolliert werden).

Die Dokumentation ist nicht sehr klar, ob diese Methode benötigt wird oder nicht, und in jedem Fall scheinen alle View-Controller, außer dem Detail, perfekt wiederhergestellt zu sein, auch ohne sie. Ich habe Code hinzugefügt, um jeden View-Controller basierend auf der letzten Pfadkomponente (d. H. Der Wiederherstellungs-ID dieses Controllers) zu instanziieren und ihn zurückzugeben.

Nun wird der decodeRestorableStateWithCoder(_:) aufgerufen, aber die Navigation geht nach einem Sekundenbruchteil immer noch auf den Top-View-Controller der Registerkarte zurück.

Also, was ist los? Was vermisse ich, um die Statuserhaltung und -wiederherstellung in einer Tab Bar + Navigations-Controller-App zu implementieren?

    
Nicolas Miari 09.09.2015, 05:26
quelle

1 Antwort

6

FIXED: Also, es gab einige Probleme mit meinem Code ...

  1. Es stellt sich heraus, dass ich in meinem Fall application(_:viewControllerWithRestorationIdentifierPath:coder:) nicht implementieren muss. (Siehe Kommentare zu dieser Antwort )

  2. Meine Implementierungen von encodeRestorableStateWithCoder(_:) und decodeRestorableStateWithCoder(_:) Rufen Sie nicht super an (wie in der akzeptierten Antwort zu der obigen Frage vorgeschlagen).

  3. Schließlich habe ich den richtigen View-Controller (Detail) angezeigt, aber der Status seiner Subviews (Inhalt des Textlabels und Hintergrundfarbe der Hauptansicht) war im ursprünglichen, leeren Zustand (wurde nicht in den letzten Zustand zurückversetzt) -ie, text label inhalt und bg farbe). Wie in diese Frage erwähnt, ist viewDidLoad () < em> nicht wird direkt nach decodeRestorableStateWithCoder(_:) aufgerufen (wie ich angenommen habe), also rufe ich stattdessen eine gemeinsame Methode von viewDidLoad() und decodeRestorableStateWithCoder(_:) auf, um die UI zu aktualisieren.

Wie üblich habe ich mich beeilt, eine Frage zu stellen, bevor ich genug Modifikationen in meinem Code durchsucht oder versucht habe (meine Entschuldigung ...).

Ich hoffe, das hilft wenigstens jemand anderem.

Wie üblich werde ich ein paar Tage warten, bevor ich meine eigene Antwort akzeptiere, falls jemand zusätzliches Licht wirft.

    
Nicolas Miari 09.09.2015, 05:55
quelle