Dave G Dave G - 1 month ago 18
Swift Question

3D Touch: Presenting From Current VC

I've successfully implemented a 3D Touch shortcut from the home screen using this code in the app delegate:

@objc(application:performActionForShortcutItem:completionHandler:) @available(iOS 9.0, *)
func application (_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler completionHandle: @escaping (Bool) -> Void) {
if shortcutItem.type == "com.myAppName.addtask" {
let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let editorVC = storyBoard.instantiateViewController(withIdentifier: "myVC_ID") as! myVC_Class
let rootVC = UIApplication.shared.keyWindow?.rootViewController
rootVC?.present(editorVC, animated: false, completion: { () -> Void in
completionHandle(true)
})
}
}


However, the problem is that it always expect to present from the root viewController. If the user leaves the app from a different VC and then tries the shortcut, I get this error:


Warning: Attempt to present xxx on (xxxx.ViewController: 0x7f9acc83e000) whose view is not in the window hierarchy!


If the user was in the app and the last view was the root VC, the shortcut from the home screen works great. So how do I make it so it works great regardless of what VC was last used?

Answer

The principle of what you're doing is absolutely right. So why isn't it working?

What I would do is make the window's root view controller a container view controller that never gets displaced — all the action happens inside it. That way, the only way the window's root view controller is not in the window hierarchy is that it has a presented view controller. And you could easily find that out by starting by finding out if it has a presented view controller and, if so, present from that.