Bei der Untersuchung eines Speicherverlusts entdeckte ich ein Problem im Zusammenhang mit der Technik des Aufrufs setRootViewController:
in einem Übergangsanimationsblock:
[UIView transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ self.window.rootViewController = newController; }
completion:nil];
Wenn der alte Ansichtscontroller (der zu ersetzende) derzeit einen anderen Ansichtscontroller anzeigt, entfernt der obige Code die dargestellte Ansicht nicht aus der Ansichtshierarchie.
Das heißt, diese Abfolge von Operationen ...
- X wird zum Root View Controller
- X zeigt Y an, sodass die Ansicht von Y auf dem Bildschirm angezeigt wird
- Verwenden Sie
transitionWithView:
, um Z zum neuen Root View Controller zu machen
... sieht für den Benutzer in Ordnung aus, aber das Debug View Hierarchy-Tool zeigt an, dass die Ansicht von Y immer noch hinter der Ansicht von Z in a vorhanden ist UITransitionView
. Das heißt, nach den drei obigen Schritten lautet die Ansichtshierarchie:
- UIWindow
- UITransitionView
- UIView (Y's Ansicht)
- UIView (Zs Ansicht)
- UITransitionView
Ich vermute, dass dies ein Problem ist, da die Ansicht von X zum Zeitpunkt des Übergangs nicht Teil der Ansichtshierarchie ist.
Wenn ich dismissViewControllerAnimated:NO
unmittelbar zuvor an X sende , transitionWithView:
lautet die resultierende Ansichtshierarchie:
- UIWindow
- UIView (X's Ansicht)
- UIView (Zs Ansicht)
Wenn ich dismissViewControllerAnimated:
(JA oder NEIN) an X sende und dann den Übergang im completion:
Block durchführe, ist die Ansichtshierarchie korrekt. Leider stört das die Animation. Wenn die Entlassung animiert wird, wird Zeit verschwendet. Wenn es nicht animiert, sieht es kaputt aus.
Ich versuche einige andere Ansätze (z. B. eine neue Container-View-Controller-Klasse als Root-View-Controller zu erstellen), habe aber nichts gefunden, was funktioniert. Ich werde diese Frage aktualisieren, wenn ich gehe.
Das ultimative Ziel ist der direkte Übergang von der dargestellten Ansicht zu einem neuen Root-Ansichts-Controller, ohne dass hier Streuansichtshierarchien verbleiben.
UIWindow
Richtige ist, aber ich hatte nicht die Zeit, viel zu experimentieren.Antworten:
Ich hatte kürzlich ein ähnliches Problem. Ich musste das manuell
UITransitionView
aus dem Fenster entfernen, um das Problem zu beheben, und dann auf dem vorherigen Root-View-Controller "Entlassen" aufrufen, um sicherzustellen, dass die Zuordnung aufgehoben wurde.Das Update ist nicht wirklich sehr schön, aber es sei denn, Sie haben seit dem Posten der Frage einen besseren Weg gefunden, es ist das einzige, was ich gefunden habe, um zu funktionieren!
viewController
ist nur dasnewController
von Ihrer ursprünglichen Frage.Ich hoffe, das hilft dir auch, dein Problem zu beheben, es ist ein absoluter Schmerz im Arsch!
(Weitere Swift-Versionen finden Sie im Bearbeitungsverlauf.)
Für eine schönere Implementierung als Erweiterung für die
UIWindow
Übergabe eines optionalen Übergangs.Verwendung:
Oder
quelle
UITransitionView
in Ihrer App, die dann als Teil der Symbole der App erfasst wird, die meiner Meinung nach vom App Store überprüft werden.Ich war mit diesem Problem konfrontiert und es hat mich einen ganzen Tag lang geärgert. Ich habe @ Richs obj-c-Lösung ausprobiert und es stellt sich heraus, dass ich mit einer leeren UITransitionView blockiert werde, wenn ich danach einen anderen viewController präsentieren möchte.
Schließlich habe ich es so herausgefunden und es hat bei mir funktioniert.
Okay, jetzt müssen Sie nur noch anrufen,
[self setRootViewController:newViewController];
wenn Sie den Root View Controller wechseln möchten.quelle
dismissViewControllerAnimated:
sieht vielleicht etwas besser aus als keine Animation. Vermeidet jedoch die GeisterUITransitionView
in der Ansichtshierarchie.Ich versuche eine einfache Sache, die für mich unter iOs 9.3 funktioniert: Entfernen Sie einfach die Ansicht des alten viewControllers während des
dismissViewControllerAnimated
Abschlusses aus seiner Hierarchie .Lassen Sie uns an der X-, Y- und Z-Ansicht arbeiten, wie von Benzado erklärt :
Welche geben:
In meinem Fall sind X und Y gut freigegeben und ihre Ansicht ist nicht mehr hierarchisch!
quelle
Hatte ein ähnliches Problem. In meinem Fall hatte ich eine viewController-Hierarchie, und einer der untergeordneten View-Controller hatte einen präsentierten View-Controller. Als ich dann den Windows-Root-View-Controller änderte, befand sich der vorgestellte View-Controller aus irgendeinem Grund noch im Speicher. Die Lösung bestand also darin, alle View-Controller zu schließen, bevor ich den Windows-Root-View-Controller ändere.
quelle
Bei der Verwendung dieses Codes bin ich auf dieses Problem gestoßen:
Durch Deaktivieren dieses Codes wurde das Problem behoben. Ich habe es geschafft, dies zum Laufen zu bringen, indem ich diese Übergangsanimation nur aktiviert habe, wenn die Filterleiste, die animiert wird, initialisiert ist.
Es ist nicht wirklich die Antwort, nach der Sie suchen, aber es könnte Sie auf den richtigen Weg bringen, um Ihre Lösung zu finden.
quelle