672 Stimmen

Versuch, einen UIViewController auf einem UIViewController zu präsentieren, dessen Ansicht sich nicht in der Fensterhierarchie befindet

Ich habe gerade begonnen, Xcode 4.5 zu verwenden, und ich habe diesen Fehler in der Konsole:

Warnung: Versuch, < finishViewController: 0x1e56e0a0 > auf < ViewController: 0x1ec3e000> zu präsentieren, dessen View nicht in der Windowshierarchie ist!

Die Ansicht wird immer noch angezeigt und alles in der App funktioniert einwandfrei. Ist das etwas Neues in iOS 6?

Dies ist der Code, den ich verwende, um zwischen den Ansichten zu wechseln:

UIStoryboard *storyboard = self.storyboard;
finishViewController *finished = 
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];

[self presentViewController:finished animated:NO completion:NULL];

15voto

Marcy Punkte 2962

Swift 5 - Hintergrund-Thread

Wenn ein Alert-Controller in einem Hintergrund-Thread ausgeführt wird, kann der Fehler "Attempt to present ... whose view is not in the window hierarchy" auftreten.

Also dies:

present(alert, animated: true, completion: nil)

Dies wurde hiermit behoben:

DispatchQueue.main.async { [weak self] in
    self?.present(alert, animated: true, completion: nil)
}

15voto

Sanbrother Punkte 585

Wahrscheinlich haben Sie, wie ich, eine falsche Wurzel viewController

Ich möchte eine ViewController in einem non-UIViewController Kontext,

Ich kann diesen Code also nicht verwenden:

[self presentViewController:]

Also, ich bekomme einen UIViewController:

[[[[UIApplication sharedApplication] delegate] window] rootViewController]

Aus irgendeinem Grund (logischer Fehler) wird die rootViewController etwas anderes als erwartet ist (eine normale UIViewController ). Dann korrigiere ich den Fehler, indem ich Folgendes ersetze rootViewController mit einer UINavigationController und das Problem ist behoben.

8voto

Aggressor Punkte 12975

TL;DR Sie können nur 1 RootViewController haben, und das ist der zuletzt präsentierte. Versuchen Sie also nicht, dass ein Viewcontroller einen anderen Viewcontroller präsentiert, wenn er bereits einen präsentiert hat, der noch nicht verworfen wurde.

Nachdem ich einige meiner eigenen Tests durchgeführt habe, bin ich zu einem Schluss gekommen.

Wenn Sie einen RootViewController haben, der alles darstellen soll, können Sie auf dieses Problem stoßen.

Hier ist mein rootController-Code (open ist meine Abkürzung für die Darstellung eines Viewcontrollers aus dem Root).

func open(controller:UIViewController)
{
    if (Context.ROOTWINDOW.rootViewController == nil)
    {
        Context.ROOTWINDOW.rootViewController = ROOT_VIEW_CONTROLLER
        Context.ROOTWINDOW.makeKeyAndVisible()
    }

    ROOT_VIEW_CONTROLLER.presentViewController(controller, animated: true, completion: {})
}

Wenn ich zweimal hintereinander "open" aufrufe (unabhängig von der verstrichenen Zeit), funktioniert das beim ersten Öffnen einwandfrei, beim zweiten Öffnen jedoch NICHT mehr. Der zweite Öffnungsversuch führt zu dem oben genannten Fehler.

Wenn ich jedoch die zuletzt dargestellte Ansicht schließe und dann open aufrufe, funktioniert es einwandfrei, wenn ich open erneut aufrufe (auf einem anderen Viewcontroller).

func close(controller:UIViewController)
{
    ROOT_VIEW_CONTROLLER.dismissViewControllerAnimated(true, completion: nil)
}

Ich bin zu dem Schluss gekommen, dass der RootViewController nur für den MOST-RECENT-CALL in der View-Hierarchie steht (auch wenn Sie ihn nicht entlassen oder einen View entfernt haben). Ich habe versucht, spielen mit allen Loader-Aufrufe (viewDidLoad, viewDidAppear, und tun verzögerte Dispatch-Aufrufe) und ich habe festgestellt, dass der einzige Weg, den ich bekommen konnte, es zu arbeiten ist NUR Aufruf vorhanden aus der obersten Ansicht-Controller.

6voto

Ashim Dahal Punkte 1049

Ich hatte ein ähnliches Problem bei Swift 4.2 aber meine Ansicht wurde nicht vom Ansichtszyklus präsentiert. Ich fand, dass ich mehrere Segue zur gleichen Zeit präsentiert werden musste. Also habe ich dispatchAsyncAfter verwendet.

func updateView() {

 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in

// for programmatically presenting view controller 
// present(viewController, animated: true, completion: nil)

//For Story board segue. you will also have to setup prepare segue for this to work. 
 self?.performSegue(withIdentifier: "Identifier", sender: nil)
  }
}

5voto

Adam Johns Punkte 33769

Mein Problem war, dass ich die Überleitung in UIApplicationDelegate 's didFinishLaunchingWithOptions Methode, bevor ich die makeKeyAndVisible() am Fenster.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X