it-swarm.com.de

Warnung: Versuchen Sie, * on * zu präsentieren, dessen Ansicht sich nicht in der Fensterhierarchie befindet - schnell

Ich versuche, eine ViewController if darzustellen, in der Daten im Datenmodell gespeichert sind. Ich erhalte jedoch den folgenden Fehler: 

Warnung: Versuch, * on * zu präsentieren, dessen Ansicht nicht in der Fensterhierarchie ist " 

Relevanter Code:

override func viewDidLoad() {
    super.viewDidLoad()
    loginButton.backgroundColor = UIColor.orangeColor()

    var request = NSFetchRequest(entityName: "UserData")
    request.returnsObjectsAsFaults = false

    var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
    var context:NSManagedObjectContext = appDel.managedObjectContext!

    var results:NSArray = context.executeFetchRequest(request, error: nil)!

    if(results.count <= 0){
        print("Inga resultat")
    } else {
        print("SWITCH VIEW PLOX")
        let internVC = self.storyboard?.instantiateViewControllerWithIdentifier("internVC") as internViewController
        self.presentViewController(internVC, animated: true, completion: nil)
    }
}

Ich habe verschiedene Lösungen ausprobiert, die Google ohne Erfolg gefunden hat.

74
Nils Wasell

Zu diesem Zeitpunkt wurde die Ansicht des View-Controllers in Ihrem Code nur erstellt, aber noch keiner Ansichtshierarchie hinzugefügt. Wenn Sie so schnell wie möglich von diesem View-Controller aus präsentieren möchten, sollten Sie dies in viewDidAppear tun, um die Sicherheit zu gewährleisten. 

110
Acey

In Ziel C: Dies löste mein Problem, wenn ViewController auf mpmovieplayer dargestellt wurde

- (UIViewController*) topMostController
{
    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }

    return topController;
}
32
akr ios

Swift 3

Ich hatte das immer als Neuling und fand heraus, dass derzeit modale Ansichten geladen werden, die abgelehnt werden können, aber zum Root-Controller zu wechseln ist am besten, wenn Sie keine modalen anzeigen müssen. 

Ich habe das benutzt

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc  = storyboard?.instantiateViewController(withIdentifier: "MainAppStoryboard") as! TabbarController
present(vc, animated: false, completion: nil)

Verwenden Sie dies stattdessen mit meinem tabController:

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let view = storyboard.instantiateViewController(withIdentifier: "MainAppStoryboard") as UIViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
//show window
appDelegate.window?.rootViewController = view

Passen Sie einfach einen Ansichts-Controller an, wenn Sie zwischen mehreren Storyboard-Bildschirmen wechseln müssen.

28
Jason

Sie müssen nur eine Auswahl mit einer Verzögerung ausführen - (0 Sekunden funktioniert). 

override func viewDidLoad() {
    super.viewDidLoad()
    perform(#selector(presentExampleController), with: nil, afterDelay: 0)
}

@objc private func presentExampleController() {
    let exampleStoryboard = UIStoryboard(named: "example", bundle: nil)
    let exampleVC = storyboard.instantiateViewController(withIdentifier: "ExampleVC") as! ExampleVC
    present(exampleVC, animated: true) 
}
13
Edward

Swift 3.

Rufen Sie diese Funktion auf, um den obersten View-Controller zu erhalten, und weisen Sie diesen View-Controller an.

func topMostController() -> UIViewController {
    var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
        while (topController.presentedViewController != nil) {
            topController = topController.presentedViewController!
        }
        return topController
    }

Verwendungszweck:

let topVC = topMostController()
let vcToPresent = self.storyboard!.instantiateViewController(withIdentifier: "YourVCStoryboardID") as! YourViewController
topVC.present(vcToPresent, animated: true, completion: nil)
12
Jacob Davis

für Swift

func topMostController() -> UIViewController {
    var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController!
    while (topController.presentedViewController != nil) {
        topController = topController.presentedViewController!
    }
    return topController
}

Schnell 4

func topMostController() -> UIViewController {
    var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
    while (topController.presentedViewController != nil) {
        topController = topController.presentedViewController!
    }
    return topController
}
3
Allen Wixted

Für Swift 3.0 und höher

public static func getTopViewController() -> UIViewController?{
if var topController = UIApplication.shared.keyWindow?.rootViewController
{
  while (topController.presentedViewController != nil)
  {
    topController = topController.presentedViewController!
  }
  return topController
}
return nil}
2
Hiren Panchal

Ich habe diese Fehlermeldung erhalten, als der Controller angezeigt wurde, nachdem der Benutzer den Deeplink geöffnet hat. Ich weiß, dass dies nicht die beste Lösung ist, aber wenn Sie sich in einem kurzen Zeitrahmen befinden, finden Sie hier eine schnelle Lösung - schreiben Sie Ihren Code einfach in asyncAfter:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.7, execute: { [weak self] in
                                navigationController.present(signInCoordinator.baseController, animated: animated, completion: completion)
                            })

Es gibt Ihrem präsentierenden Controller Zeit, viewDidAppear aufzurufen.

1
Bohdan Savych

Ich habe so viele Ansätze ausprobiert! Das einzig Nützliche ist:

if var topController = UIApplication.shared.keyWindow?.rootViewController
{
  while (topController.presentedViewController != nil)
  {
    topController = topController.presentedViewController!
  }
}
1
Xiaohan Chen
let storyboard = UIStoryboard(name: "test", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "teststoryboard") as UIViewController
UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true, completion: nil)

Dies schien zu funktionieren, um sicherzustellen, dass es die oberste Ansicht ist. 

Ich habe einen Fehler erhalten

Warnung: Versuch, myapp.testController: 0x7fdd01703990 auf myapp.testController: 0x7fdd01703690 zu präsentieren, dessen Ansicht nicht in der Fensterhierarchie ist!

Hoffe, das hilft anderen mit Swift 3

1
Jason

Alle Implementierungen für topViewController unterstützen hier nicht vollständig die Fälle, in denen Sie UINavigationController oder UITabBarController verwenden.

Für UITabBarController und UINavigationController benötigen Sie eine andere Implementierung.

Hier ist der Code, den ich verwende, um topMostViewController zu erhalten:

protocol TopUIViewController {
    func topUIViewController() -> UIViewController?
}

extension UIWindow : TopUIViewController {
    func topUIViewController() -> UIViewController? {
        if let rootViewController = self.rootViewController {
            return self.recursiveTopUIViewController(from: rootViewController)
        }

        return nil
    }

    private func recursiveTopUIViewController(from: UIViewController?) -> UIViewController? {
        if let topVC = from?.topUIViewController() { return recursiveTopUIViewController(from: topVC) ?? from }
        return from
    }
}

extension UIViewController : TopUIViewController {
    @objc open func topUIViewController() -> UIViewController? {
        return self.presentedViewController
    }
}

extension UINavigationController {
    override open func topUIViewController() -> UIViewController? {
        return self.visibleViewController
    }
}

extension UITabBarController {
    override open func topUIViewController() -> UIViewController? {
        return self.selectedViewController ?? presentedViewController
    }
}
1

Anstatt einen Top-View-Controller zu finden, kann man verwenden

viewController.modalPresentationStyle = UIModalPresentationStyle.currentContext

Der ViewController ist der Controller, den Sie präsentieren möchten. Dies ist nützlich, wenn in der Hierarchie verschiedene Arten von Ansichten vorhanden sind, z

Den anderen Präsentationsstil finden Sie unter Apple doc

0
Akhil Dad

Die vorherigen Antworten beziehen sich auf die Situation, in der der Ansichtscontroller, der eine Ansicht 1) darstellen soll, noch nicht zur Ansichtshierarchie hinzugefügt wurde, oder 2) nicht der Draufsichtscontroller ist.
Eine andere Möglichkeit besteht darin, dass eine Warnung angezeigt wird, während bereits eine andere Warnung angezeigt und noch nicht abgewiesen wurde.

0