Search code examples
swiftuipageviewcontroller3dtouchrootviewcontrollerquickaction

go directly to different page using quick Action shortcut in swift


my app has 2 pages(VCs) which are created and being controlled in a BossPageViewController and I want to give the user an option of going directly to second page using a Shortcut action. now I know how to create shortcuts and how to trigger them and I also know how to open that page as root but when I open it as root I no longer can swipe to first page and also the pageDots aren't there so I should close the app and run it again to be able to swipe between pages and see pageDots.

code below is where second page shortcut triggers, I did copy and past the whole sceneDelegate here, maybe someone wants to test it:

import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {

var window: UIWindow?
var shortcutItemManager: UIApplicationShortcutItem?

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    if let shortcutItem = connectionOptions.shortcutItem {
        shortcutItemManager = shortcutItem
    }
    guard let _ = (scene as? UIWindowScene) else { return }
}

func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
    shortcutItemManager = shortcutItem
}

//MARK:- Shortcuts are Triggered here.

func sceneDidBecomeActive(_ scene: UIScene) {
    if let shortcutItem = shortcutItemManager {

        if shortcutItem.type == "com.x.appname.openSecondPage" {



            ///- tag: code lines that run secondPage as root VC

            if let windowScene = scene as? UIWindowScene {
               let window = UIWindow(windowScene: windowScene)
             let storyboard = UIStoryboard(name: "Main", bundle: nil)
               window.rootViewController = storyboard.instantiateViewController(withIdentifier: "SecondPageVC")
               self.window = window
               window.makeKeyAndVisible()



            }
            shortcutItemManager = nil
         }

        }  
      }
   }

I also don't want to instantiate the page as popover or modal or anything else I mean just want that page as it is and not the copy of that page. code example of what I mean as copy:

            let openSecondPage = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "SecondPageVC") as! SecondPageViewController
            window?.rootViewController?.present(openSecondPage, animated: false, completion: nil)

I have been searching for a month but there wasn't anything exactly like this, they were similar but their code solution wasn't for me, that's why I did post this.


Solution

  • Swift 5.1

    Ok by mixing and doing trial and error on different codes posted on Stackoverflow for different questions, finally I made that work for me as I wanted and I thought It's better to share it cause I know someone will need it or may have better approach to this that can share with us.

    Use the code bellow where shortcut Item gets triggered or if you want to run it on app launch use it inside *****func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions)***** in sceneDelegate.

    if let windowScene = scene as? UIWindowScene {
    
    
                    let window = UIWindow(windowScene: windowScene)
                    let bossPageVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "BossPageVCID") as! BossPageViewController
    
                    self.window = window
    
                    UIView.transition(with: window, duration: 0.1, options: .transitionCrossDissolve, animations: {
    
                        window.rootViewController = bossPageVC
                        window.makeKeyAndVisible()
    
                    }, completion: { completed in
                        // viewControllerPages is a viewController array I created in BossPageViewController and index of 1 means the second page
                        if let secondPage = bossPageVC.viewControllerPages[1]
                            bossPageVC.setViewControllers([secondPage], direction: .forward, animated: true, completion: nil)
    
                    })
                }