【问题标题】:Swift - pushViewController from appDelegate, rootViewController.navigationController is nilSwift - 来自 appDelegate 的 pushViewController,rootViewController.navigationController 为 nil
【发布时间】:2014-10-05 01:16:48
【问题描述】:

在遵循一些指南时遇到问题,特别是 http://blog.originate.com/blog/2014/04/22/deeplinking-in-ios/

我正在设置 url 方案,并且从另一个应用程序启动该应用程序运行良好,但传入主机或 url 并不能正常工作。我正在为所有视图布局使用故事板和界面构建器。

指南在 appDelegate 中显示了这个 openURL:

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

这是我从其他几个来源快速简化的版本,即 Get Instance Of ViewController From AppDelegate In Swift我目前正在跳过 url 主机的条件以删除问题中潜在的其他变量。

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

}

swift 版本导致崩溃: fatal error: unexpectedly found nil while unwrapping an Optional value

好像rootViewController还没有navigationController?

【问题讨论】:

    标签: ios swift uiviewcontroller uinavigationcontroller appdelegate


    【解决方案1】:

    在我的例子中,rootViewController 似乎实际上是 UINavigationController 类型,因此在声明中强制转换它允许我直接在其上调用 pushToViewController。

    func application(application: UIApplication, openURL url: NSURL, sourceApplication: String, annotation: AnyObject?) -> Bool {
        let rootViewController = self.window!.rootViewController as! UINavigationController
        let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let profileViewController = mainStoryboard.instantiateViewController(withIdentifier: "InstructionVC") as! InstructionVC
        rootViewController.pushViewController(profileViewController, animated: true)
        return true
    
    }
    

    【讨论】:

    • 我知道这已经有一年了,但我想知道,如果你推送到你实例化的新视图控制器,这算作你可以准备继续的地方吗?
    • 谢谢谢谢谢谢。遵循一些指南,这些指南只是从情节提要中获取导航控制器,但它不起作用,这就是诀窍!
    【解决方案2】:

    SWIFT 4: 使用条件绑定和链接的安全推送方式

    if let navController = self.navigationController, let viewController = self.storyboard?.instantiateViewController(withIdentifier: "indentfier") as? CustomViewController{
        navController.pushViewController(viewController, animated: true)
    }
    

    一行代码:

    斯威夫特 3:

    self.navigationController!.pushViewController(self.storyboar‌​d!.instantiateViewCo‌​ntroller(withIdentif‌​ier: "view2") as UIViewController, animated: true)
    

    self.navigationController!.pushViewController(self.storyboard!.instantiateViewControllerWithIdentifier("view2") as UIViewController, animated: true)
    

    【讨论】:

    • 斯威夫特 2.0 self.navigationController!.pushViewController(self.storyboard?.instantiateViewControllerWithIdentifier("view2") as! UIViewController, animated: true)
    • Swift 3.0 self.navigationController!.pushViewController(self.storyboard!.instantiateViewController(withIdentifier: "view2") as UIViewController, animated: true)
    • self.navigationController 为零。你是怎么推的?
    • @Umitk PushViewController 是 Navigation API 的一部分。因此,如果没有“UINavigationController”,您将继续推送任何内容。更新了处理推送的最安全方法的答案
    【解决方案3】:

    APPDELEGATE 到页面:

            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)
    

    逐页:

            let loginPageView = self.storyboard?.instantiateViewControllerWithIdentifier("scoutPageID") as! ScoutPage
            self.navigationController?.pushViewController(loginPageView, animated: true)
    

    【讨论】:

    • 这是我在几个小时内看到的唯一有用的帖子。谢谢。一页一页是我一直在寻找的。​​span>
    【解决方案4】:

    为 swift 3/4 更新。 投票最多的“一行代码”不起作用,因为“self”中没有导航控制器

    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)
    

    【讨论】:

    • 我在你的解决方案中没有找到窗口
    • @RishabhDugar 你在 AppDelegate 课上吗?
    • 不,我在我的控制器文件中
    • 解决方案是从应用委托中获取导航控制器,而不是视图控制器。在您的情况下,上面的“一行代码”解决方案可能对您有用。
    • 信号SIGABRT上线rootViewController
    【解决方案5】:

    从 AppDelegate 推送视图控制器的 Swift 3 和 4 最佳实践:

    if let rootViewController = self.window!.rootViewController as? UINavigationController {
       let storyboard = UIStoryboard(name: "Main", bundle: nil)
    
       if let viewcontroller = storyboard.instantiateViewController(withIdentifier: "DiscussionBoardSID") as? DiscussionBoardViewController {
          viewcontroller.postID = "13" ///pass data to your viewcontroller
          rootViewController.pushViewController(viewcontroller, animated: true)
       }
    }
    

    【讨论】:

      【解决方案6】:

      如果你想用 NavigationBar 或 Dismiss(Animated: true, completion: nil) 来展示和关闭 在 didFinishLaunchingWithOptions

      中设置 addObserver
      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
      
      
      
      NotificationCenter.default.addObserver(self, selector: #selector(devolucionNoPresencial), name: NSNotification.Name(rawValue: "DevolucionNoPresencial"), object: nil)
              return true
      }
      

      然后在你的方法中

      func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
      //do your code for .active, .inactive .background, etc
      
       if let userInfo = response.notification.request.content.userInfo as? [String : AnyObject] {
                  if UIApplication.shared.applicationState == .active {
      //activate the notificationCenter so you can call your @objc method
      NotificationCenter.default.post(name: NSNotification.Name(rawValue: "DevolucionNoPresencial"), object: nil)
      }
      

      添加@objc方法

      @objc private func devolucionNoPresencial() {
      
      
             //change DevolucionVC for VC you want to present
      
              if let controller = DevolucionVC() as? DevolucionVC {
                  if let window = self.window, let rootViewController = window.rootViewController {
                      var currentController = rootViewController
                      while let presentedController = currentController.presentedViewController {
                          currentController = presentedController
                      }
                      currentController.present(controller, animated: true, completion: nil)
                  }
              }
      
          }
      
      }
      

      【讨论】:

        【解决方案7】:
        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)
                    }
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-05-26
          • 2020-11-02
          • 1970-01-01
          • 2017-11-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多