从由 UIApplicationShortcutItem 触发的 AppDelegate 导航到 ViewController
Navigating to a ViewController from AppDelegate triggered by UIApplicationShortcutItem
在我的应用程序中,启动的第一个视图由 RootUIViewController
控制。现在用户可以点击此视图上的任何按钮,然后 segue
进入由 LeafUIViewController
控制的视图。每个按钮都指向相同的视图,但某些参数具有不同的值。
现在我已经实现了 3D Touch 快捷菜单,它在 AppDelegate
:
中正确调用了以下函数
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void)
在这个函数中,我想转到 LeafUIViewController
,这样用户仍然可以导航回 RootViewController
。
这样做的正确方法是什么,以便 Root 被正确实例化,压入堆栈,然后视图导航到 Leaf?
我建议不要从该回调中执行任何特定的启动操作。我通常设置一个全局状态并在我所有相关的 viewcontroller 中处理它。他们通常会跳到主 viewcontroller。在那里,我以编程方式执行操作,就像用户通常所做的那样。
优点是 viewcontroller 层次结构以正常方式初始化。然后可以由将要显示在屏幕上的第一个 viewcontroller 处理状态,这不一定是应用程序的第一个 viewcontroller。当用户触发操作时,应用程序可能已经初始化。所以层次结构中可能有一个随机的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,这可能不是最好的。如果有更好的东西,我很乐意学习:)
在我的应用程序中,启动的第一个视图由 RootUIViewController
控制。现在用户可以点击此视图上的任何按钮,然后 segue
进入由 LeafUIViewController
控制的视图。每个按钮都指向相同的视图,但某些参数具有不同的值。
现在我已经实现了 3D Touch 快捷菜单,它在 AppDelegate
:
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void)
在这个函数中,我想转到 LeafUIViewController
,这样用户仍然可以导航回 RootViewController
。
这样做的正确方法是什么,以便 Root 被正确实例化,压入堆栈,然后视图导航到 Leaf?
我建议不要从该回调中执行任何特定的启动操作。我通常设置一个全局状态并在我所有相关的 viewcontroller 中处理它。他们通常会跳到主 viewcontroller。在那里,我以编程方式执行操作,就像用户通常所做的那样。
优点是 viewcontroller 层次结构以正常方式初始化。然后可以由将要显示在屏幕上的第一个 viewcontroller 处理状态,这不一定是应用程序的第一个 viewcontroller。当用户触发操作时,应用程序可能已经初始化。所以层次结构中可能有一个随机的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,这可能不是最好的。如果有更好的东西,我很乐意学习:)