ios swift hierarchy presentviewcontroller

ios - Advertencia: Intente presentar*en*cuya vista no esté en la jerarquía de ventanas-swift



hierarchy presentviewcontroller (12)

Para Swift 3.0 y superior

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

Estoy intentando presentar un ViewController si hay datos guardados en el modelo de datos. Pero me sale el siguiente error:

Advertencia: Intente presentar * en * cuya vista no se encuentre en la jerarquía de ventanas "

Código relevante:

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) } }

He intentado diferentes soluciones encontradas utilizando Google sin éxito.


En el objetivo c: Esto resolvió mi problema al presentar el controlador de visualización en la parte superior de mpmovieplayer

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


En este punto de su código, la vista del controlador de vista solo se ha creado, pero no se ha agregado a ninguna jerarquía de vistas. Si desea presentar desde ese controlador de vista lo antes posible, debe hacerlo en viewDidAppear para ser más seguro.


En lugar de encontrar el controlador de vista superior, uno puede usar

viewController.modalPresentationStyle = UIModalPresentationStyle.currentContext

Donde viewController es el controlador que desea presentar. Esto es útil cuando hay diferentes tipos de vistas en jerarquía como TabBar, NavBar, aunque otras parecen ser correctas pero son más bien hackers.

El otro estilo de presentación se puede encontrar en Apple Doc.


He intentado tantos approches! Lo único útil es:

if var topController = UIApplication.shared.keyWindow?.rootViewController { while (topController.presentedViewController != nil) { topController = topController.presentedViewController! } }


Solo necesita realizar un selector con un retraso - (0 segundos funciona).

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) }


Swift 3

Tuve que seguir apareciendo como un novato y descubrí que el presente carga las vistas modales que se pueden descartar, pero es mejor cambiar al controlador raíz si no es necesario mostrar un modal.

Estaba usando esto

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

Usando esto en su lugar con mi 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

Solo ajuste a un controlador de vista si necesita cambiar entre múltiples pantallas de guión gráfico.


Swift 3.

Llame a esta función para obtener el controlador de vista superior, luego tenga ese controlador de vista presente.

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

Uso:

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


Swift 4

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


Toda la implementación de topViewController aquí no es totalmente compatible con los casos cuando tiene UINavigationController o UITabBarController , para esos dos necesita un manejo un poco diferente:

Para UITabBarController y UINavigationController necesita una implementación diferente.

Aquí está el código que estoy usando para obtener topMostViewController:

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 } }


para SWIFT

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


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)

Esto parece funcionar para asegurarse de que sea la vista más superior.

Estaba recibiendo un error

Advertencia: Intente presentar myapp.testController: 0x7fdd01703990 en myapp.testController: 0x7fdd01703690 cuya vista no se encuentra en la jerarquía de ventanas!

Espero que esto ayude a otros con swift 3