I have four application shortcuts set up when force pressing my app icon. I have a tab bar controller with navigation controllers each with table view controllers as the root view controller for the first two tabs.
For the shortcuts, how can I open either the first or second tab and select a row from the corresponding table view?
I think I would start with this but please correct me if I'm wrong.
let tabNav:UINavigationController = tabBar.viewControllers?[0] as! UINavigationController
---EDIT--- After working with the answer provided, I have this somewhat working.
let navigationController = tabBar.viewControllers![0] as! UINavigationController
let tableViewController = navigationController.viewControllers.first as! FederationTableViewController
let indexPath = IndexPath(row: 0, section: 0)
tableViewController.tableView.selectRow(at: indexPath, animated: true, scrollPosition: .top)
tableViewController.tableView.delegate?.tableView!((tableViewController.tableView)!, didSelectRowAt: indexPath)
tabBar.selectedIndex = 0
This selects the correct row and opens the correct view controller. The issue I'm having with it now is that it is pushing the view controller for the selected row twice so the view controller that is pushed when selecting that row is being loaded twice.
You need to receive the shortcut item in app delegate, then take appropriate action based on the type of shortcut that you will have defined in info.plist
. Something like this should work, though it may need amending based on the exact structure of your app or your subclass names etc.
In App Delegate:
func application(_ application: UIApplication, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
print("Opening app from 3D touch shortcut...")
completionHandler(handleShortcut(shortcutItem: shortcutItem))
}
// This function handles the shortcut. Any problems will return false, preventing the shortcut opening.
private func handleShortcut(shortcutItem: UIApplicationShortcutItem) -> Bool {
if shortcutItem.type == "firstShortcutType" {
guard let tabBarController = self.window.rootViewController as? UITabBarController else { return false }
guard let navigationController = tabBarController.viewcontrollers[0] as? UINavigationController else { return false }
guard let tableViewController = navigationController.rootViewController as? UITableViewController else { return false }
// Select index of tab bar controller
tabBarController.selectedIndex = 0
// TableView May not be loaded, so I wrap this in a delayed block
DispatchQueue.main.asyncAfter(deadline: .now()+1, execute: {
// Create index path
let indexPath = IndexPath(row: 0, section: 0)
self.tableViewController.tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
})
return true
} else if shortcutItem.type == "otherShortcutType" {
// Handle ofher shortcut types
} else {
return false
}
}