Переход к ViewController из AppDelegate, запускаемого UIApplicationShortcutItem
В моем приложении первое запущенное представление контролируется RootUIViewController
, Теперь пользователь может нажать на любую из кнопок в этом представлении, а затем segue
на вид, контролируемый LeafUIViewController
, Каждая кнопка указывает на одно и то же представление с разными значениями для некоторых аргументов.
Теперь я реализовал контекстное меню 3D Touch, которое правильно вызывает следующую функцию в AppDelegate
:
func application(application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void)
В этой функции я хочу перейти к LeafUIViewController
так что пользователь все еще может вернуться к RootViewController
,
Как правильно сделать это так, чтобы Root правильно создавался, помещался в стек и затем просматривал навигацию к Листу?
1 ответ
Я не рекомендую делать какие-либо действия по запуску определенных переходов от этого обратного вызова. Я обычно устанавливаю глобальное состояние и обрабатываю его во всех соответствующих контроллерах представления. Они обычно всплывают на главном viewcontroller. Там я делаю действия программно, как обычно делает пользователь.
Преимущество состоит в том, что иерархия viewcontroller инициализируется обычным способом. Состояние может затем обрабатываться первым viewcontroller, который будет отображаться на экране, который не обязательно является первым viewcontroller приложения. Приложение может быть уже инициализировано, когда пользователь запускает действие. Таким образом, в иерархии может быть случайный view-контроллер.
Я использую что-то вроде:
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
}
а затем в main 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
}
И в других ВК:
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. Если есть что-то лучше, я бы хотел узнать это:)