Ich habe gerade angefangen, Xcode 4.5 zu verwenden und habe diesen Fehler in der Konsole erhalten:
Warnung: Versuchen Sie, <finishViewController: 0x1e56e0a0> auf <ViewController: 0x1ec3e000> anzuzeigen, dessen Ansicht nicht in der Fensterhierarchie enthalten ist!
Die Ansicht wird noch angezeigt und alles in der App funktioniert einwandfrei. Ist das etwas Neues in iOS 6?
Dies ist der Code, mit dem ich zwischen Ansichten wechsle:
UIStoryboard *storyboard = self.storyboard;
finishViewController *finished =
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];
[self presentViewController:finished animated:NO completion:NULL];
presentViewController:animated:completion
einen Navigationscontroller aufzurufen . Tun Sie dies im App-Delegaten?Antworten:
Woher rufen Sie diese Methode auf? Ich hatte ein Problem, bei dem ich versuchte, einen Modal View Controller innerhalb der
viewDidLoad
Methode zu präsentieren. Die Lösung für mich bestand darin, diesen Aufruf auf dieviewDidAppear:
Methode zu verschieben.Meine Vermutung ist , dass die Ansicht des View - Controller ist nicht in der Ansichtshierarchie des Fensters an dem Punkt , dass es geladen worden ist (wenn die
viewDidLoad
Nachricht gesendet wird), aber es ist in der Hierarchie - Fenster , nachdem sie dargestellt worden ist (wenn dieviewDidAppear:
Nachricht gesendet wird ) .Vorsicht
Wenn Sie einen Anruf tätigen zu tun
presentViewController:animated:completion:
in derviewDidAppear:
Sie in ein Problem laufen kann , wodurch die modal - View - Controller immer vorgestellt wird , wenn die Sicht erscheint die View - Controller (das macht Sinn!) Und so die modale View - Controller präsentiert wird nie weggehen .. .Möglicherweise ist dies nicht der beste Ort, um den Modal View Controller zu präsentieren, oder es muss ein zusätzlicher Status beibehalten werden, der es dem Presenting View Controller ermöglicht, zu entscheiden, ob er den Modal View Controller sofort präsentieren soll oder nicht.
quelle
Eine weitere mögliche Ursache:
Ich hatte dieses Problem, als ich versehentlich zweimal denselben View Controller präsentierte. (Einmal mit
performSegueWithIdentifer:sender:
dem wurde aufgerufen, als die Taste gedrückt wurde, und ein zweites Mal mit einem direkt mit der Taste verbundenen Segue).Tatsächlich feuerten zwei Segues gleichzeitig und ich bekam den Fehler:
Attempt to present X on Y whose view is not in the window hierarchy!
quelle
present(viewController, animated: true, completion: nil)
einer Schleife angerufen .viewWillLayoutSubviews
undviewDidLayoutSubviews
(iOS 5.0+) können für diesen Zweck verwendet werden. Sie werden früher als viewDidAppear aufgerufen.quelle
Verwenden Sie zum Anzeigen einer Unteransicht zur Hauptansicht den folgenden Code
Verwenden Sie den folgenden Code, um eine Unteransicht aus der Hauptansicht zu entfernen
quelle
Dieses Problem trat auch auf, als ich versuchte, ein
UIViewController
In zu präsentierenviewDidLoad
. James Bedfords Antwort funktionierte, aber meine App zeigte zuerst 1 oder 2 Sekunden lang den Hintergrund.Nach einigen Recherchen habe ich einen Weg gefunden, dies mit dem zu lösen
addChildViewController
.quelle
Wahrscheinlich hast du wie ich eine falsche Wurzel
viewController
Ich möchte ein
ViewController
in einem anzeigennon-UIViewController
Kontext ,Ich kann solchen Code also nicht verwenden:
Also bekomme ich einen UIViewController:
Aus irgendeinem Grund (logischer Fehler) ist das
rootViewController
etwas anderes als erwartet (normalUIViewController
). Dann korrigiere ich den Fehler, ersetze ihnrootViewController
durch aUINavigationController
und das Problem ist weg.quelle
TL; DR Sie können nur 1 rootViewController und den zuletzt vorgestellten haben. Versuchen Sie also nicht, dass ein Viewcontroller einen anderen Viewcontroller präsentiert, wenn dieser bereits einen nicht entlassenen präsentiert.
Nachdem ich einige meiner eigenen Tests durchgeführt habe, bin ich zu einem Schluss gekommen.
Wenn Sie einen rootViewController haben, auf dem Sie alles präsentieren möchten, kann dieses Problem auftreten.
Hier ist mein rootController-Code (offen ist meine Verknüpfung zum Präsentieren eines Viewcontrollers aus dem Stammverzeichnis).
Wenn ich zweimal hintereinander aufrufe (unabhängig von der verstrichenen Zeit), funktioniert dies beim ersten Öffnen einwandfrei, beim zweiten Öffnen jedoch NICHT. Der zweite offene Versuch führt zu dem obigen Fehler.
Wenn ich jedoch die zuletzt präsentierte Ansicht schließe und dann open aufrufe, funktioniert dies einwandfrei, wenn ich open erneut aufrufe (auf einem anderen Viewcontroller).
Ich bin zu dem Schluss gekommen, dass sich der rootViewController nur des MOST-RECENT-CALL in der Ansichtshierarchie befindet (auch wenn Sie ihn nicht geschlossen oder eine Ansicht entfernt haben). Ich habe versucht, mit allen Loader-Aufrufen zu spielen (viewDidLoad, viewDidAppear und verzögerte Versandanrufe), und ich habe festgestellt, dass ich es nur zum Laufen bringen kann, wenn ich NUR vom obersten View-Controller anwesend bin.
quelle
wait
wait
decide
push screen to front
und es ist UNMÖGLICH, ist IOS ????Mein Problem war, dass ich die Segue-In
UIApplicationDelegate
-didFinishLaunchingWithOptions
Methode durchführte, bevor ichmakeKeyAndVisible()
das Fenster anrief.quelle
In meiner Situation war ich nicht in der Lage, meine in eine Klassenüberschreibung zu versetzen. Also, hier ist was ich habe:
quelle
Ich hatte das gleiche Problem. Ich musste einen Navigationscontroller einbetten und den Controller durch ihn präsentieren. Unten ist der Beispielcode.
quelle
Wenn Sie ein AVPlayer-Objekt mit abgespieltem Video haben, müssen Sie zuerst das Video anhalten.
quelle
Ich hatte das gleiche Problem. Das Problem war, dass performSegueWithIdentifier durch eine Benachrichtigung ausgelöst wurde, sobald ich die Benachrichtigung in den Hauptthread legte, war die Warnmeldung verschwunden.
quelle
Es funktioniert gut, versuchen Sie es. Verknüpfung
quelle
Für den Fall, dass es jemandem hilft, war mein Problem extrem dumm. Völlig meine Schuld natürlich. Eine Benachrichtigung löste eine Methode aus, die das Modal aufrief. Aber ich habe die Benachrichtigung nicht richtig entfernt, sodass ich irgendwann mehr als eine Benachrichtigung hatte, sodass das Modal mehrmals aufgerufen wurde. Nachdem Sie das Modal einmal aufgerufen haben, befindet sich der Viewcontroller, der es aufruft, natürlich nicht mehr in der Ansichtshierarchie. Deshalb sehen wir dieses Problem. Meine Situation verursachte auch eine Reihe anderer Probleme, wie Sie es erwarten würden.
Zusammenfassend lässt sich also sagen , dass das Modal nicht mehr als einmal aufgerufen wird .
quelle
Am Ende habe ich einen solchen Code gefunden, der für mich endlich funktioniert (Swift), wenn man bedenkt, dass Sie einige
viewController
von praktisch überall anzeigen möchten . Dieser Code stürzt offensichtlich ab, wenn kein rootViewController verfügbar ist. Das ist das offene Ende. Es beinhaltet auch nicht den normalerweise erforderlichen Wechsel zum UI-Thread mitquelle
Diese Art von Warnung kann bedeuten, dass Sie versuchen, Neues
View Controller
durch zu präsentieren,Navigation Controller
während diesNavigation Controller
gerade ein anderes präsentiertView Controller
. Um dies zu beheben, müssen Sie die aktuell zuerst präsentierteView Controller
und nach Fertigstellung die neue präsentieren. Eine andere Ursache für die Warnung kann sein, dass versucht wird, einenView Controller
anderen Thread als zu präsentierenmain
.quelle
Ich hatte ein ähnliches Problem mit Swift 4.2, aber meine Ansicht wurde nicht aus dem Ansichtszyklus dargestellt. Ich stellte fest, dass ich mehrere Abschnitte gleichzeitig präsentieren musste. Also habe ich dispatchAsyncAfter verwendet.
quelle
Ich habe es behoben, indem ich die
start()
Funktion innerhalb desdismiss
Abschlussblocks verschoben habe:Start enthält zwei Aufrufe an
self.present()
einen für einen UINavigationController und einen für einenUIImagePickerController
.Das hat es für mich behoben.
quelle
Sie können diese Warnung auch erhalten, wenn Sie einen Übergang von einem Ansichtscontroller durchführen, der in einen Container eingebettet ist. Die richtige Lösung besteht darin, Segue vom übergeordneten Container und nicht vom View Controller des Containers zu verwenden.
quelle
Müssen unter Zeile schreiben.
anstatt
in UIViewController
quelle
Mit Swift 3 ...
Eine andere mögliche Ursache dafür, die mir passiert ist, war ein Übergang von einer tableViewCell zu einem anderen ViewController im Storyboard. Ich habe auch verwendet
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {}
wenn die Zelle angeklickt wurde.Ich habe dieses Problem behoben, indem ich von ViewController zu ViewController gewechselt bin.
quelle
Ich hatte dieses Problem und die Hauptursache war das mehrfache Abonnieren eines Button-Click-Handlers (TouchUpInside).
Es wurde in ViewWillAppear abonniert, das mehrmals aufgerufen wurde, seit wir die Navigation hinzugefügt hatten, um zu einem anderen Controller zu wechseln und dann wieder dorthin zurückzukehren.
quelle
Mir ist passiert, dass der Abschnitt im Storyboard irgendwie kaputt war . Das Löschen des Segues (und das erneute Erstellen des exakten Segues) löste das Problem.
quelle
In Ihrem Hauptfenster wird es wahrscheinlich immer Zeiten mit Übergängen geben, die mit der Anzeige einer Warnung nicht kompatibel sind. Damit Sie jederzeit in Ihrem Anwendungslebenszyklus Warnungen anzeigen können, sollten Sie über ein separates Fenster verfügen, in dem Sie die Aufgabe ausführen können.
Grundlegende Verwendung, die von Natur aus immer erfolgreich sein wird:
quelle
Leider hat die akzeptierte Lösung für meinen Fall nicht funktioniert. Ich habe versucht, direkt nach dem Abwickeln von einem anderen View Controller zu einem neuen View Controller zu navigieren.
Ich fand eine Lösung, indem ich ein Flag verwendete, um anzuzeigen, welcher Abwicklungsabschnitt aufgerufen wurde.
Dann präsentieren Sie die gewünschte VC mit
present(_ viewControllerToPresent: UIViewController)
Grundsätzlich kann ich mit dem obigen Code das Abwickeln von Login / SignUp VC abfangen und zum Dashboard navigieren oder die Abwicklungsaktion von Passwort vergessen VC abfangen und zur Anmeldeseite navigieren.
quelle
Ich habe diesen Fehler behoben, indem ich den obersten Viewcontroller in einer Konstanten gespeichert habe, die sich während des Zyklus über rootViewController befindet:
quelle
Ich habe festgestellt, dass dieser Fehler nach der Aktualisierung von Xcode aufgetreten ist. Ich glaube, Swift 5 . Das Problem trat auf, als ich direkt nach dem Abwickeln eines View Controllers programmgesteuert einen Segue startete.
Die Lösung wurde gefunden, als ein verwandter Fehler behoben wurde. Der Benutzer konnte nun Segues durch Wischen auf der Seite abwickeln. Dies hat die Logik meines Programms gebrochen.
Dies wurde behoben, indem der Präsentationsmodus auf allen Ansichtssteuerungen von Automatisch auf Vollbild geändert wurde .
Sie können dies im Attributfenster im Interface Builder tun. In dieser Antwort erfahren Sie, wie Sie dies programmgesteuert tun.
quelle
Ich hatte gerade auch dieses Problem, aber es hatte nichts mit dem Timing zu tun. Ich habe einen Singleton verwendet, um Szenen zu verarbeiten, und ich habe ihn als Moderator festgelegt. Mit anderen Worten, "Selbst" war an nichts gebunden. Ich habe gerade seine innere "Szene" zum neuen Moderator gemacht und voila, es hat funktioniert. (Voila verliert seine Berührung, nachdem Sie seine Bedeutung gelernt haben, heh).
Also ja, es geht nicht darum, "auf magische Weise den richtigen Weg zu finden", sondern zu verstehen, wo Ihr Code steht und was er tut. Ich bin froh, dass Apple eine so einfache englische Warnmeldung gegeben hat, auch mit Emotionen. Ein großes Lob an den Apfelentwickler, der das getan hat !!
quelle
Wenn andere Lösungen aus irgendeinem Grund nicht gut aussehen, können Sie diese gute alte
workaround
Darstellung mit der Verzögerung von 0 wie folgt verwenden :Ich habe zwar keine dokumentierte Garantie dafür gesehen, dass sich Ihr VC in der Ansichtshierarchie befindet, wenn die Ausführung des Versandblocks geplant ist, aber ich habe festgestellt, dass dies einwandfrei funktioniert.
Die Verwendung einer Verzögerung von z. B. 0,2 Sekunden ist ebenfalls eine Option. Und das Beste - auf diese Weise müssen Sie sich nicht mit booleschen Variablen anlegen
viewDidAppear:
quelle
Dies funktioniert, um einen beliebigen Ansichts-Controller anzuzeigen, wenn Sie einen Navigations-Controller zur Verfügung haben. self.navigationController? .present (MyViewController, animiert: true, Vervollständigung: nil) Außerdem kann ich auch Warnungen und Mail-Controller präsentieren.
quelle