ios - the - Swift-pushViewController de appDelegate, rootViewController.navigationController es nulo
set root view controller programmatically swift (5)
Tener un problema después de algunas guías, específicamente http://blog.originate.com/blog/2014/04/22/deeplinking-in-ios/
Estoy configurando el esquema de URL y está funcionando bien para iniciar la aplicación desde otra aplicación, pero pasar el host o la URL no funciona como debería. Estoy usando storyboards y constructor de interfaz para todos los diseños de vista.
La guía muestra este openURL en appDelegate:
-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
if([[url host] isEqualToString:@"page"]){
if([[url path] isEqualToString:@"/page1"]){
[self.mainController pushViewController:[[Page1ViewController alloc] init] animated:YES];
}
return YES;
}
}
Aquí está mi versión simplificada y rápida de algunas otras fuentes, es decir, obtener instancia de ViewController desde AppDelegate. En Swift estoy omitiendo el condicional para el host de la url en este momento para eliminar posibles otras variables en el problema.
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String, annotation: AnyObject?) -> Bool {
var rootViewController = self.window!.rootViewController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var profileViewController = mainStoryboard.instantiateViewControllerWithIdentifier("profile") as ProfileViewController
rootViewController.navigationController.popToViewController(profileViewController, animated: true)
return true
}
La versión rápida causa un bloqueo: fatal error: unexpectedly found nil while unwrapping an Optional value
Parece que rootViewController aún no tiene un navigationController?
Parece que rootViewController en realidad es del tipo UINavigationController en mi caso, por lo que al convertirlo en declaración me permitió llamar a pushToViewController directamente sobre él.
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String, annotation: AnyObject?) -> Bool {
var rootViewController = self.window!.rootViewController as UINavigationController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
var profileViewController = mainStoryboard.instantiateViewControllerWithIdentifier("profile") as ProfileViewController
rootViewController.pushToViewController(profileViewController, animated: true)
return true
}
APPDELEGAR A LA PÁGINA:
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let loginPageView = mainStoryboard.instantiateViewControllerWithIdentifier("leadBidderPagerID") as! LeadBidderPage
var rootViewController = self.window!.rootViewController as! UINavigationController
rootViewController.pushViewController(loginPageView, animated: true)
PÁGINA A PÁGINA:
let loginPageView = self.storyboard?.instantiateViewControllerWithIdentifier("scoutPageID") as! ScoutPage
self.navigationController?.pushViewController(loginPageView, animated: true)
func pushNewView() {
if let wind = UIApplication.sharedApplication().delegate?.window {
if let rootViewController = wind?.rootViewController {
let viewToPush = YourViewController()
let nav1 = UINavigationController(rootViewController: viewToPush)
if let alreadySomeOneThere = rootViewController.presentedViewController {
alreadySomeOneThere.presentViewController(nav1, animated: true, completion: nil)
}else {
rootViewController.presentViewController(nav1, animated: true, completion: nil)
}
}
}
}
En una línea de código:
Swift 3:
self.navigationController!.pushViewController(self.storyboard!.instantiateViewController(withIdentifier: "view2") as UIViewController, animated: true)
self.navigationController!.pushViewController(self.storyboard!.instantiateViewControllerWithIdentifier("view2") as UIViewController, animated: true)
Actualizado para swift 3/4. La "línea de código" más votada no funciona porque no hay un controlador de navegación en "sí mismo"
let rootViewController = self.window!.rootViewController as!
UINavigationController
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let profileViewController = mainStoryboard.instantiateViewController(withIdentifier: "ProfileViewController") as! ProfileViewController
rootViewController.pushViewController(profileViewController, animated: true)