在 SWIFT 2.x 中以编程方式使用 NavigationController 调用 UIViewController

Posted

技术标签:

【中文标题】在 SWIFT 2.x 中以编程方式使用 NavigationController 调用 UIViewController【英文标题】:Call a UIViewController with NavigationController programmatically in SWIFT 2.x 【发布时间】:2016-01-12 14:42:17 【问题描述】:

当我选择动态快捷方式时,我想以编程方式调用带有在 Storyboard 中设计的 NavigationController 的 UIViewController。

我在 Main.storyboard 中设计了我的 UIViewController 及其 NavigationController,并放置了一个故事板 ID(我称之为 MyUICtrlStoryID)

为了创建我的动态快捷方式,我在 AppDelegate 中编写了以下代码:

@available(ios 9.0, *)
    func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: Bool -> Void) 




        let handledShortCutItem = shortcutItem.type // handleShortCutItem(shortcutItem)

        if handledShortCutItem == "3DTouchShourtcutID"

            self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

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

//FirstViewcontroller UI will be called as root UIView
            let initialViewControlleripad : FirstViewController = storyboard.instantiateViewControllerWithIdentifier("FirstViewControllerID") as! FirstViewController



            initialViewControlleripad.go2MySecondUI = true   //set this check variable in order to launch my second UI View from the first one.

            self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
            self.window?.rootViewController = initialViewControlleripad
            self.window?.makeKeyAndVisible()
        
      

在我的 FistViewController 的 viewWillAppear 函数中

if #available(iOS 9.0, *) 

                let shortcutItem = UIApplicationShortcutItem(type: "3DTouchShortcutID",
                    localizedTitle:    "This action",
                    localizedSubtitle: "action description",
                    icon: UIApplicationShortcutIcon(type: UIApplicationShortcutIconType.Add),
                    userInfo: nil)


                UIApplication.sharedApplication().shortcutItems = [shortcutItem]

                //check if FirstViewControler had to call the second UI 
                if go2MySecondUI == true 
                    self.go2MySecondUI = false


                            let newViewCtrl = self.storyboard?.instantiateViewControllerWithIdentifier("MyUICtrlStoryID") as? SecondViewController
                           // call second UI view

                   dispatch_async(dispatch_get_main_queue()) 
                       self.presentViewController(newViewCtrl!, animated: true, completion: nil)
                   
                                              //  
                

这段代码运行良好:当我通过 3d 触摸选择我的快捷方式时,我的 secondviewcontroller 将被调用,并且它的 UIView 将被显示......但没有它的导航控制器。 否则,如果我通过情节提要中设计的按钮(带有相关的 segue 回调)调用我的 secondUIcontroller,则 secondUIView 将正确显示导航控制器..

怎么了?

【问题讨论】:

为什么要推送视图控制器然后呈现相同的视图控制器? self.navigationController?.pushViewController(newViewCtrl!, animated: true) dispatch_async(dispatch_get_main_queue()) self.presentViewController(newViewCtrl!, animated: true, completion: nil) @beyowulf:呃,对不起!我忘记删除它.. 但是,当然,它不能解决我的问题:S 推送不存在(即删除 dispatch_async(dispatch_get_main_queue()) self.presentViewController(newViewCtrl!, animated: true, completion: nil) 并说 self.navigationController?.pushViewController(newViewCtrl !, animated: true) 确保 self.navigationController 不为零。更好的方法可能是调用 self.preformSegueWithIdentifier @beyowulf 不幸的是,如果我使用 self.navigationController?.pushViewController(newViewCtrl!, animated: true) 它将不起作用。此外,在 Swift 2.1 中,您必须使用 dispatch_async(dispatch_get_main_queue()) 你想知道为什么视图控制器不在导航控制器中。这是因为您以模态方式呈现它。你需要说一些类似 self.navigationController.pushViewController 或 self.navigationController.showViewController 的东西。这仅在 firstViewController 本身嵌入到 navigationController 时才有效。如果可以分派到主队列,但只有当该方法可能从 viewWillAppear 不会调用的不同线程调用时才需要。 【参考方案1】:

您需要将您的第一个视图控制器嵌入到 UINavigationController 中。所以在 AppDelegate 中你的代码应该是:

@available(iOS 9.0, *)
    func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: Bool -> Void) 




        let handledShortCutItem = shortcutItem.type // handleShortCutItem(shortcutItem)

        if handledShortCutItem == "3DTouchShourtcutID"

            self.window = UIWindow(frame: UIScreen.mainScreen().bounds)

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

//FirstViewcontroller UI will be called as root UIView
            let initialViewControlleripad : FirstViewController = storyboard.instantiateViewControllerWithIdentifier("FirstViewControllerID") as! FirstViewController



            initialViewControlleripad.go2MySecondUI = true   //set this check variable in order to launch my second UI View from the first one.
            let navigationController = UINavigationController(rootViewController: initialViewControlleripad)

            self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
            self.window?.rootViewController = navigationController
            self.window?.makeKeyAndVisible()
        
      

然后在 FirstViewController 的 viewWillAppear 中,您需要推送第二个视图控制器而不是存在。所以你的代码应该是:

if #available(iOS 9.0, *) 

                let shortcutItem = UIApplicationShortcutItem(type: "3DTouchShortcutID",
                    localizedTitle:    "This action",
                    localizedSubtitle: "action description",
                    icon: UIApplicationShortcutIcon(type: UIApplicationShortcutIconType.Add),
                    userInfo: nil)


                UIApplication.sharedApplication().shortcutItems = [shortcutItem]

                //check if FirstViewControler had to call the second UI 
                if go2MySecondUI == true 
                    self.go2MySecondUI = false


                            let newViewCtrl = self.storyboard?.instantiateViewControllerWithIdentifier("MyUICtrlStoryID") as? SecondViewController
                           // call second UI view

                           self.navigationController?.pushViewController(newViewCtrl, animated: true)

                                              //  
                

【讨论】:

以上是关于在 SWIFT 2.x 中以编程方式使用 NavigationController 调用 UIViewController的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中以编程方式将 UILabel 对象居中?

UIScrollView 在 Swift 中以编程方式

使用 Cocoa 在 Swift 4.0 中以编程方式创建复选框的标准方法是啥?

如何在swift中以编程方式减少obj文件

在 Swift 中以编程方式创建 NSTextField

在 Swift 中以编程方式突出显示 UITableViewCell