【问题标题】:Present a specific view controller from notification action从通知操作中呈现特定的视图控制器
【发布时间】:2017-02-09 14:35:48
【问题描述】:

我正在处理本地通知,我正在尝试提供一个特定的 viewController,但我已经尝试了我在这个论坛中找到的内容,但我得到了一个不寻常的行为,其中显示的视图 this picture here: 这是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() 方法)? 任何帮助将不胜感激。

【问题讨论】:

  • 目前有效吗?
  • 看源代码上面的图片,视图控制器不应该是空白的。

标签: swift viewcontroller appdelegate unusernotificationcenter usernotifications


【解决方案1】:

我刚刚找到了答案。它基本上是从 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()
}

感谢Opening view controller from app delegate using swift

【讨论】:

  • 我也这样设置 rootViewController 但问题是我的默认 rootView 是午餐动画视图。它将显示一个动画,然后它将重定向到另一个视图并将其设置为 rootView。但是当我将我的 rootView 重置为didReceive response:时,它会显示特定的 ViewController 以便一目了然,然后返回到旧的 rootViewController。如何防止它回到旧的 rootViewController?
【解决方案2】:

当您必须在当前屏幕上显示特定的视图控制器时,无论您是通过导航推送还是显示视图控制器都没有关系,在这两种情况下,您都可以使用下面的代码来解决您的问题。

                    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)
                        }
                    }

【讨论】:

    【解决方案3】:

    您不能在导航控制器上显示视图控制器。您需要让 topviewcontroller 呈现。以下是执行此操作的代码:-

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

    使用以下方法获取顶视图控制器:-

    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 func是:-

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

    【讨论】:

      【解决方案4】:

      在 Swift 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)
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-27
        • 1970-01-01
        相关资源
        最近更新 更多