【问题标题】:Routing to a specific view controller from the app delegate. Swift从应用程序委托路由到特定的视图控制器。迅速
【发布时间】:2019-03-03 15:33:38
【问题描述】:

我正在使用 Firebase 动态链接并跟随 firebases 在线视频。处理传入 URL 后,我想将用户路由到应用程序上的特定页面。我的应用程序结构如下所示。

UITabBarController 作为具有 3 个选项卡的 rootViewController -> UINavigationController -> UIViewController(全部在情节提要中完成)

如所见:

当我得到一个特定的 URL 时,我想转到包含一些数据的第一个选项卡,然后从那里将用户发送到正确的页面。这确保用户仍然可以通过导航返回。

我试图通过这个来实现:

var storyBoard = UIStoryboard()
    storyBoard = UIStoryboard(name: "Main", bundle: nil)

    let tabViewController = storyBoard.instantiateViewController(withIdentifier: "tabBar") as! TabBar

    let homeVC = storyBoard.instantiateViewController(withIdentifier: "homePage") as! NewHomeViewController
    homeVC.navigatorItem = DeepLinkItem(listId: mediaID, itemId: itemID)

    let appdelegate = UIApplication.shared.delegate as! AppDelegate
    appdelegate.window!.rootViewController = tabViewController

通过homeVC.navigatorItem = DeepLinkItem(listId: mediaID, itemId: itemID) 行,我可以看到数据已设置完成,因为我的所有打印语句都来自其他视图控制器,但我仍然停留在主页上(第一个视图标签栏)并且用户没有被引导到正确的页面。

是否有人知道如何从应用委托路由到另一个视图控制器,同时仍将标签栏保持为根。谢谢。

这就是我所追求的:

所以从 appDelegate,我想从标签栏到导航控制器,然后到第一个视图控制器一直到最终视图控制器,确保我保持导航路径。我所做的是将数据传递给第一个视图控制器,然后依次遍历每个视图控制器。但这行不通。我认为这是由于我正在设置根视图控制器的应用程序委托。谢谢。

编辑

我找到了this 对与我类似的帖子的回答。

我的代码现在看起来像这样:

    let mainStoryBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let tabBarController = mainStoryBoard.instantiateViewController(withIdentifier: "tabBar") as! UITabBarController
    let homeNavigationController = tabBarController.viewControllers?.first as! UINavigationController
    let homeView = mainStoryBoard.instantiateViewController(withIdentifier: "homePage") as! NewHomeViewController

    homeView.navigatorItem = DeepLinkItem(listId: mediaID, itemId: itemID)

    homeNavigationController.pushViewController(homeView, animated: false)

    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = tabBarController
    self.window?.makeKeyAndVisible()

目前它不起作用,只是带有标签栏的空白屏幕。但是,将根视图控制器更改为 homeNavigationController 有效,它只是标签栏不再存在。

【问题讨论】:

    标签: ios swift deep-linking


    【解决方案1】:

    如果我对您的理解正确,您希望以位于目标视图控制器的状态启动您的应用。如果应用程序已在运行,则此答案不适用。

    首先,你需要实例化标签栏控制器。这将返回您在情节提要文件中构建的整个层次结构。 UITabBarController 的 viewControllers 属性将包含您为不同选项卡设置的三个 UINavigationController。第一个导航控制器是与您的主页选项卡关联的。然后,您可以操纵UINavigationController 的viewControllers 属性来更改视图控制器的初始堆栈。 UINavigationController 将始终显示最后一个,因此在此示例中,thirdVc 是主页选项卡中显示的那个。

    func setupAppFromDeeplink() {
        let tabBarController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "tabBar") as! UITabBarController
        let homeNavigationController = tabBarController.viewControllers?.first as! UINavigationController
    
        let firstVc = UIViewController() 
        let secondVc = UIViewController()
        let thirdVc = UIViewController()
    
        homeNavigationController.viewControllers = [firstVc, secondVc, thirdVc]
    
        window!.rootViewController = tabBarController
    }
    

    您将无法使用这种方法通过 segues 传递数据,您也不应该这样做。在设置firstVc等时分配要在视图控制器中显示的数据。

    【讨论】:

    • 谢谢。我将如何设置数据?这将与初始化程序一起使用吗?我真正想做的就是使用来自 URL 的数据将用户带到第一个 VC。我不想以任何方式更改应用程序。有没有办法做到这一点?
    • @AndrewHarris 当您设置视图控制器时(无论是像我一样使用 init 或通过情节提要 id 获取它们),您对视图控制器的引用与您在继续。在我的示例中,如果 firstVc 有一个名为 url 的属性,您可以通过执行 firstVc.url = yourDeepLinkUrl 来设置它
    猜你喜欢
    • 2015-11-05
    • 1970-01-01
    • 2015-08-22
    • 2011-12-29
    • 2013-10-29
    • 2020-09-20
    • 2021-05-30
    • 2015-08-16
    • 1970-01-01
    相关资源
    最近更新 更多