N3tMaster
N3tMaster

Reputation: 493

Call a UIViewController with NavigationController programmatically in SWIFT 2.x

I want to call a UIViewController with NavigationController designed in Storyboard programmatically when I select a dynamic shortcut.

I designed my UIViewController and its NavigationController in Main.storyboard and I put a storyboard ID (I called it MyUICtrlStoryID)

In order to create my dynamic shortcut I wrote the following code in the 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()
        }
      }

in the viewWillAppear function of my FistViewController

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)
                   }
                                              //  }
                }

This code works fine: when I select, by 3d touch, my shortcut, my secondviewcontroller will be call and its UIView will be showed .. but without its navigation controller. otherwise if I call my secondUIcontroller by a button designed in storyboard (with related segue callback) the secondUIView will be showed with navigation controller correctly..

What is wrong?

Upvotes: 0

Views: 949

Answers (1)

beyowulf
beyowulf

Reputation: 15321

You need to embed your first view controller in a UINavigationController. So in the AppDelegate your code should be:

@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()
        }
      }

Then in viewWillAppear of the FirstViewController you need to push the second view controller rather than present. So your code should read:

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)

                                              //  }
                }

Upvotes: 1

Related Questions