从 AppDelegate 显示 ViewController,它显示了,但导航栏未激活,我无法从那里转换到任何其他视图

Presenting a ViewController from the AppDelegate, it shows up but the navbar is not active and I can not transition to any other view from there

我有一个监听用户位置变化的功能,并且我想根据某些条件在故事板上打开一个视图控制器。单击单元格时,通常会从 tableviewconroller 打开此视图控制器。我想要的是从 appdelegate 过渡到这个视图控制器。我一直在尝试使用此网站上类似 post 的许多代码组合,但其中 none 正确加载了页面,因此我可以在之后使用导航。这是我最接近的:

 if(site != nil){

        if (currentExhibitionSiteId != site?.ID) {

            currentExhibitionSiteId = (site?.ID)!


            let storyboard  = UIStoryboard(name: "Main", bundle: nil)

            let detailViewController = storyboard.instantiateViewControllerWithIdentifier("DetailViewController") as!DetailViewController
            detailViewController.site = site

            let locTable = storyboard.instantiateViewControllerWithIdentifier("sitesTable") as! LocationsTableViewController



            let frontNav = UINavigationController.init(rootViewController: detailViewController)

            let rearNav = UINavigationController.init(rootViewController: locTable)

            let mainRoot = SWRevealViewController.init(rearViewController: rearNav, frontViewController: frontNav)

            self.window?.rootViewController = mainRoot
            self.window?.makeKeyAndVisible()


        }
    }

this is the how it stays in the storyboard

我会手动转场并调用 ViewController.performSegueWithIdentifier(...) 而不是这种方法。这会让你做一个 show segue 并保留 UINavigationController 对象上的导航栏。

UINavigationController 中嵌入 DetailViewController。从 Story Board 自定义您的 NavigationBar。给这个导航控制器一个StoryboardID。让它成为 MyNavVC。然后修改你的代码为

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let navController = storyboard.instantiateViewControllerWithIdentifier("MyNavVC") as? UINavigationController

    (navController.rootViewController as! DetailViewController)!.site = site
    self.window!.rootViewController = navController
    self.window!.makeKeyAndVisible()

无需覆盖现有的rootViewController。您可以尝试稍微重新构建您的结构并使原始的 rootViewController 成为 UINavigationController。然后你可以通过 show call 添加一个 detailViewController

在初始设置的 AppDelegate 中,它可能看起来像这样....

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {  
    if let window = self.window {

         if let window = self.window {

        window.makeKeyAndVisible()
        navController =  window.rootViewController as? UINavigationController
    }
    return true
}

您还可以将对主 UINavigationController 的引用存储为 属性。 var navController: UINavigationController? 或者您可以每次从 window.rootViewController.

施放

然后,您的主故事板将包含一个 UINavigationController,一个 UITableViewController 连接到它,然后是您希望在有人单击单元格时显示的 DetailViewController。我为此制作了一个基本的故事板,它看起来像这样。

请记住,您需要 select UINavigationController 属性 检查器上的 isInitialViewController 才能完成这项工作。

当你想触发一个视图移动到现有视图之上时,即在你的 onLocationChanged 方法中,你可以引用那个 navController 属性 来添加一个视图

 func onLocationChanged(location: CLLocationCoordinate2D) {

    let site: ExhibitionSite? = self.exhibitionSiteRepository.findClosestSite(location)


    if(site != nil){

        if (currentExhibitionSiteId != site?.ID) {
             currentExhibitionSiteId = (site?.ID)!
             let storyboard = UIStoryboard(name: "Main", bundle: nil)
             let detailViewController = storyboard.instantiateViewControllerWithIdentifier("DetailViewController") as? DetailViewController
            detailViewController!.site = site

            navController?.showViewController(detailViewController, sender: self)
        }

 } 

此处您正在加载主情节提要并通过其标识符请求 DetailViewController。确保 DetailViewController 已填写标识符,以便您可以访问它,否则它会崩溃。

如果您不希望它像 navigationController 动画一样推送到屏幕上,那么您可以将该调用更改为 .presentViewController(detailViewController, animated: false, completion:nil),然后它将在您现有的视图上弹出一个完整的模式。

希望这对您有所帮助,我不确定您是如何使用此 SWRevealMenuController 的,以及它如何影响您的 Storyboard。根据我对 SWRevealMenuController 的了解,它接管了您的一些层次结构,因此将所有位置更改的内容移动到 UINavigationController 下的顶视图控制器中可能是有意义的。看起来没有任何理由需要将 locationChanged 内容放在 AppDelegate 上。如果你运行遇到问题,我可以仔细看看。