Ich habe eine Anwendung, die aus der Anwendungsvorlage mit Registerkarten erstellt wurde. (ARC, iOS 4)
Problem
Nun, wenn ModalViewCont auf dem Bildschirm erscheint, indem Sie die Home-Taste drücken, um die Anwendung im Hintergrund zu platzieren und nachdem Sie die Anwendung zurückgeholt haben, wird die ViewCont2-Ansicht nicht geschlossen, sondern ein schwarzer Bildschirm mit der Tableiste unten. Das gleiche passiert, ohne den Hintergrund / Vordergrund der Anwendung zu setzen; Wenn andere Tabs angetippt werden, bevor Sie auf die Registerkarte 2. tippen. ( BEARBEITEN: Dies geschieht nur, wenn self.view in der Ansicht "nill" auf "nil" anstelle von "viewDidDisappear" gesetzt ist.)
Ich habe festgestellt, dass ViewCont2 eine neue Ansicht lädt (die Referenz wurde überprüft), aber die Superansicht der Ansicht ist null, so dass die neue Ansicht nicht angezeigt wird, sondern ein schwarzer Bildschirm.
Dinge, die nicht funktioniert haben
Lösungen, die ich in Betracht gezogen habe;
_
%Vor%Fragen
BEARBEITEN: Es scheint, dass wenn viewDidLoad früher aufgerufen wird als es sollte (d. h. wenn view in viewWillDisappear anstelle von viewDidDisappear angezeigt wird), superview nicht gesetzt ist.
Es scheint seltsam, aber Ihr Vorschlag (1) ist in der Tat ein korrekter Workaround für dieses Problem:
%Vor%Ihr zweiter Vorschlag ist gut für die Leistung (weil Laden von Ansichten ist eine teure Operation) - aber es wird das Problem nicht lösen. Sie können auch mit einem schwarzen Bildschirm enden, ohne die Ansicht in der folgenden Situation auf Null zu setzen (testen Sie dies im iOS-Simulator):
Im Allgemeinen können Sie davon ausgehen, dass in viewDidLoad die view -Eigenschaft festgelegt ist und in viewWillAppear + viewDidAppear die Ansicht der Ansichtshierarchie hinzugefügt wurde. Daher sollte der Superview zu diesem Zeitpunkt vorhanden sein (Hier ist der Superview eine private Ansicht des TabbarControllers der Klasse UIViewControllerWrapperView). In unserem Fall wird die Ansicht zwar neu geladen (zum Zeitpunkt der App-Wiederaufnahme), aber nicht zur Ansichtshierarchie hinzugefügt, was zu einem schwarzen Bildschirm führt. Dies scheint ein Fehler in UITabBarController zu sein.
Die Problemumgehung zwingt die Appearance Selectors erneut ausgeführt werden. Also wird viewWillAppear erneut aufgerufen, diesmal mit einer Superview. Auch viewDidAppear wird zweimal aufgerufen!
Das Einstellen von self.view auf null ist in Ordnung, sollte aber in den meisten Fällen nicht notwendig sein. Lassen Sie das System entscheiden, wann die Ansicht entladen werden soll (iOS kann Ansichten entladen, wenn der Speicher knapp wird). Der View-Controller-Code sollte so gestaltet sein, dass die Benutzeroberfläche jederzeit neu konfiguriert werden kann, ohne die Ansicht neu laden zu müssen.
Sie haben keine vollständige Kontrolle darüber, wann Ansichten geladen und entladen werden, und Sie dürfen Ansichten nicht manuell manuell laden / entladen.
Stattdessen sollten Sie sich das Laden / Entladen von Ansichten als etwas vorstellen, das vollständig Ihrem UIViewController
s entspricht, wobei Sie nur für Folgendes verantwortlich sind:
loadView
manuell implementieren. viewDidLoad
, viewWillUnload
und viewDidUnload
, die vom View-Controller aufgerufen werden, wenn es entscheidet, seine Ansicht zu laden / zu entladen. Die Tatsache, dass Sie keine vollständige Kontrolle über haben, wenn die oben genannten Callbacks aufgerufen werden, hat Auswirkungen darauf, was in sie gehen soll.
In Ihrem Fall, wenn ich es richtig verstehe, möchten Sie jedes Mal, wenn die Ansicht Ihres ViewCont2 verschwindet, es zurücksetzen, so dass es, wenn es wieder erscheint, in einem "sauberen" Zustand ist. Ich würde diesen Zustand in einigen Methoden implementieren, und rufen Sie beide von viewDidLoad
und von viewDidDisappear
. Alternativ können Sie die Logik "clean" in viewWillAppear
haben.
Oder möchten Sie die ViewCont2-Ansicht nur bereinigen, wenn die aktuelle Schaltfläche angetippt wird? Löschen Sie in diesem Fall die Ansicht sowohl in viewDidLoad
als auch, wenn Sie auf die Schaltfläche tippen.
Ich biete an, dass, wenn der modale Ansichts-Controller aktiv ist und Sie die Ansicht ablehnen, dass Sie den Navigationsansicht-Controllern viewControllers eine neue Ansicht hinzufügen, diese Ansicht den Vorgänger entfernen soll.
Sie können mit meinem Projekt spielen, um zu sehen, ob Sie glauben, dass es für Sie funktioniert.
>EDIT: Mein Kommentar zu der ausgewählten Antwort ist, dass diese Technik offensichtlich jetzt funktioniert, aber ich habe es selbst schwer, ihr zu folgen. Der Code in meinem Projekt verwendet das System auf einfache und direkte Weise - wenn die modale Ansicht aufgefordert wird, sich selbst zu verwerfen, ruft sie eine Methode auf (könnte in jeder Klasse sein), die dem Array des Navigationscontrollers eine neue Ansicht hinzufügt und sich dann selbst ablehnt . Für ein bisschen Zeit gibt es zwei View-Controller der gleichen Zeit, die neue über die alte gestapelt. Wenn der neue View-Controller erscheint, entfernt er im Hintergrund und unsichtbar den unerwünschten viewController vom Stapel der Nab-Leiste, und puh, er verschwindet.
Ich habe die tatsächliche Lösung für den UITabBarController-Fehler gefunden (Speicherwarnung, App, zurück / Vordergrund eingeben, Modal ablehnen). Die Ursache des Fehlers ist die Verwendung von UITabBarController als Root-View-Controller. Wir könnten also einen anderen View-Controller als Root-View-Controller verwenden und die Tab-Leiste daraus darstellen. Ich habe es auf iOS 5.1 Simulator getestet.
Natürlich ist der Overhead von extra UIViewController umstritten. Außerdem ist es gegen die Apple-Dokumentation;
%Vor%Im Gegensatz zu anderen View-Controllern sollte ein Tab-Bar-Interface niemals als Kind eines anderen View-Controllers installiert werden. UITabBarController Klassenreferenz
Ich habe andere Lösungen gefunden;
Der erste bewirkt die Warnung: "Es wird erwartet, dass Anwendungsfenster am Ende des Anwendungsstarts einen Root-View-Controller haben", obwohl es einen Root-View-Controller gibt.
Obwohl es kludgy erscheint, wird der temporäre View-Controller mit dem ersten freigegeben.
.
%Vor%Ich denke, du solltest die Ansicht nicht null zuweisen. Wenn ich Sie richtig verstanden habe, möchten Sie den Inhalt jedes Mal aktualisieren / neu laden, wenn die Ansicht erscheint. Anstatt also die Ansicht auf null zu setzen, sollten Sie versuchen, sie zu aktualisieren. Sie können es tun, indem Sie hinzufügen:
%Vor%Bitte sagen Sie mir, ob ich Ihr Problem richtig verstanden habe
Tags und Links objective-c view ios superview