从UIApplicationShortcutItem触发,从AppDelegate导航到ViewController

时间:2016-01-19 05:33:31

标签: swift ios9 3dtouch uiapplicationshortcutitem

在我的应用程序中,启动的第一个视图由RootUIViewController控制。现在,用户可以点按此视图上的任意按钮,然后点按segue到由LeafUIViewController控制的视图。每个按钮都指向同一个视图,某些参数的值不同。

现在我已经实现了 3D Touch快捷菜单,它正确调用了AppDelegate中的以下功能:

func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void)

在此功能中,我想转到LeafUIViewController,以便用户仍然可以导航回RootViewController

正确的方法是什么,以便正确实例化 Root ,在堆栈上推送,然后查看导航到 Leaf

1 个答案:

答案 0 :(得分:1)

我建议不要从该回调中执行特定segue的任何启动操作。我通常设置一个全局状态并在所有相关的viewcontrollers中处理它。它们通常弹出到主视图控制器。在那里,我以编程方式执行操作,就像用户通常所做的那样。

优点是viewcontroller层次结构以正常方式初始化。然后状态可以由将要显示在屏幕上的第一个视图控制器处理,该屏幕不一定是应用程序的第一个视图控制器。当用户触发操作时,应用程序可能已经初始化。因此,层次结构中可能存在随机视图控制器。

我用的是:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    if #available(iOS 9.0, *) {
        if let shortcutItem = launchOptions?[UIApplicationLaunchOptionsShortcutItemKey] as? UIApplicationShortcutItem {
            handleShortcutItem(shortcutItem)
        }
    }
    return true
}

enum ShortcutType: String {
    case myAction1 = "myAction1"
    case myAction2 = "myAction2"
}

@available(iOS 9.0, *)
func handleShortcutItem(shortcutItem: UIApplicationShortcutItem) -> Bool {

    if let shortcutType = ShortcutType.init(rawValue: shortcutItem.type) {

        switch shortcutType {
            case .myAction1:
                MyHelper.sharedInstance().actionMode = 1
                return true
            case .myAction2:
                MyHelper.sharedInstance().actionMode = 2
                return true
            default:  
               return false
        }
    }
    return false
}

然后在主viewController(如主菜单)中以某种方式处理动作:

override func viewDidAppear() {
    super.viewDidAppear()
    switch MyHelper.sharedInstance().actionMode {
            case 1:
                // react on 1 somehow - such as segue to vc1
            case 2:
                // react on 2 somehow - such as segue to vc2
        default:  
            break
    }
    // clear the mode
    MyHelper.sharedInstance().actionMode = 0
}

在其他vc中:

override func viewDidLoad() {
    super viewDidLoad()
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "reloadView", name: UIApplicationWillEnterForegroundNotification, object: nil)
}

func reloadView() {
    if MyHelper.sharedInstance().actionMode {
        self.navigationController.popToRootViewControllerAnimated(false) 
    }
}

如果您使用多个vc,这可能不是最好的。如果有更好的东西,我很乐意了解:)