Представьте конкретный контроллер представления из действия уведомления

Я работаю с локальными уведомлениями и пытаюсь представить конкретное viewController, но я попробовал то, что нашел на этом форуме, и получил необычное поведение с представлением, показанным на это изображение здесь: А вот исходный код AppDelegate.swift:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

    print("didReceive Method called")

    if response.actionIdentifier == "actionOne" {
        DispatchQueue.main.async(execute: {
            self.notificationAction1()
        })
    } else if response.actionIdentifier == "actionTwo" {
        DispatchQueue.main.async(execute: { 
            self.notificationAction2()
        })

    } else if response.actionIdentifier == "actionThree" {

    }
    completionHandler()
}

func notificationAction1() {
    redirectToVC()
}

func redirectToVC() {
    let toVC = VersesViewController()
    if self.window != nil && self.window?.rootViewController != nil {
        let rootVC = self.window?.rootViewController!
        if rootVC is UINavigationController {
            (rootVC as! UINavigationController).pushViewController(toVC, animated: true)
        } else {
            rootVC?.present(toVC, animated: true, completion: { 
                //Do something
            })
        }
    }
}

Что не так с кодом (особенно с методом redirectToVC())? Любая помощь будет оценена.


person techcoderx    schedule 09.02.2017    source источник
comment
Это в настоящее время работает?   -  person Mannopson    schedule 09.02.2017
comment
Посмотрите на картинку над исходным кодом, контроллер представления пуст, чего быть не должно.   -  person techcoderx    schedule 10.02.2017


Ответы (4)


Я только что нашел ответ на это. По сути, это контроллер представления от AppDelegate.

func redirectToVC() {
    let mainStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let initialViewController: UIViewController = mainStoryboard.instantiateViewController(withIdentifier: "versesVC") as UIViewController
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = initialViewController
    self.window?.makeKeyAndVisible()
}

Благодаря открытию контроллера представления из делегата приложения с помощью swift

person techcoderx    schedule 10.02.2017
comment
Я также установил rootViewController таким образом, но проблема в том, что мой rootView по умолчанию - это представление анимации ланчера. Он покажет анимацию, а затем перенаправит на другой вид и установит его как rootView. Но когда я сбрасываю свой rootView в didReceive response:, он сразу показывает этот конкретный ViewController, а затем возвращается к старому rootViewController. Как я могу предотвратить его возврат к старому rootViewController? - person sz ashik; 26.02.2018

Всякий раз, когда вам нужно представить конкретный контроллер представления на текущем экране, не имеет значения, протолкнули ли вы контроллер представления через навигацию или могли бы быть представлены, в обоих случаях вы можете использовать приведенный ниже код для решения вашей проблемы.

                    var appdelgateObj = UIApplication.shared.delegate as! AppDelegate
                    if let destinationVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: “ToPresentVC”) as? ToPresentVC {
                        if let window = appdelgateObj.window , let rootViewController = window.rootViewController {
                            var currentController = rootViewController
                            while let presentedController = currentController.presentedViewController {
                                currentController = presentedController
                            }
                            currentController.present(destinationVC, animated: true, completion: nil)
                        }
                    }
person Harish Rathuri    schedule 19.09.2017

Вы не можете представить контроллер просмотра на контроллере навигации. Вам нужно получить представление topviewcontroller. Ниже приведен код для этого: -

    guard let topVC = UIApplication.getTopViewController() else {
        return
    }
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
        self.launchViewController(topVC)
    }

Получите контроллер Top View, используя: -

extension UIApplication {

class func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {

    if let nav = base as? UINavigationController {
        return getTopViewController(base: nav.visibleViewController)

    } else if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
        return getTopViewController(base: selected)

    } else if let presented = base?.presentedViewController {
        return getTopViewController(base: presented)
    }
    return base
  }
}

И функция launchViewController: -

class func launchViewController(_ sender: UIViewController) {
        let vc: Viewcontroller = storyboard.instantiateViewController(withIdentifier: "Viewcontroller") as! Viewcontroller
        sender.navigationController?.present(vc, animated: true, completion: nil)
    }
person iOS Developer    schedule 12.06.2020

В Свифт 5

Создайте переменную в классе Appdelegate:

    let window : UIWindow? = UIWindow()

и используйте функцию ниже, откуда вам нужно перенаправить:

func navigateToVCOne() {
    if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "pbVC") as? ProblemViewController {
        if let window = self.window, let rootViewController = window.rootViewController {
            var currentController = rootViewController
            while let presentedController = currentController.presentedViewController {
                currentController = presentedController
            }
            currentController.present(controller, animated: true, completion: nil)
        }
    }
}
person Anil Kumar    schedule 12.06.2020