【问题标题】:Dismiss View Controller Doesn't Working in Helper Class Swift关闭视图控制器在帮助类 Swift 中不起作用
【发布时间】:2019-02-26 11:21:49
【问题描述】:

所以我有一个如下所示的辅助类:

class Helper {
   static func handleTokenInvalid() {
        DispatchQueue.main.async {
                UIViewController().dismiss()
        }
    }
}

extension UIViewController {
    func dismiss() {
        let root = UIApplication.shared.keyWindow?.rootViewController
        root?.dismiss(animated: true, completion: nil)    }
}

我想关闭所有打开并返回到应用程序根目录的视图控制器。但是它不起作用。如果我在普通视图控制器中做同样的事情是可行的。有人知道解决方案吗?谢谢!

编辑: 我也已经试过了,但是它说在包装可选值时发现了 nil。

func dismiss() {
        self.view.window!.rootViewController?.dismiss(animated: true, completion: nil)
    }

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    你所做的一切

    UIViewController().dismiss
    

    正在创建一个新的视图控制器并将其关闭。 您必须在实际呈现的 View 控制器实例上调用dismiss。

    【讨论】:

    • 怎么做?
    • 如果这不起作用: self.view.window?.rootViewController?.dismiss(animated: true, completion: nil) 您可能正在推动视图控制器(通过导航控制器),这应该可以工作: self.navigationController?.popToRootViewController(animated: true)
    • 我也试过这个,但它不起作用。故事板有什么问题吗?
    • 它没有回答,我找到了我已经在这个问题中回答的替代方案。感谢您的帮助!
    【解决方案2】:

    两天后找到关闭我的控制器的正确方法但找不到任何东西,因为我认为 Xcode 发现我当前的控制器是 nil。相反,我使用这个:

    let viewController = UIStoryboard(name: "DashboardPreLogin", bundle: Bundle.main).instantiateViewController(withIdentifier: "TabBarPreLoginViewController")
    
    let appDel: AppDelegate = UIApplication.shared.delegate as! AppDelegate
    appDel.window?.rootViewController = nil
    appDel.window?.rootViewController = viewController
    UIView.transition(with: appDel.window!, duration: 0.5, options: UIViewAnimationOptions.transitionCrossDissolve, animations: {() -> Void in appDel.window?.rootViewController = viewController}, completion: nil)
    

    这将关闭视图控制器并替换为新控制器。

    【讨论】:

      【解决方案3】:
      extension UIApplication {
          class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
              if let navigationController = controller as? UINavigationController {
                  return topViewController(controller: navigationController.visibleViewController)
              }
              if let tabController = controller as? UITabBarController {
                  if let selected = tabController.selectedViewController {
                      return topViewController(controller: selected)
                  }
              }
              if let presented = controller?.presentedViewController {
                  return topViewController(controller: presented)
              }
              return controller
          }
      }
      

      你可以在 Helper 类的任何地方使用它

      if let topController = UIApplication.topViewController() {
         topController.dismiss(animated: true, completion: nil)
      }
      

      【讨论】:

      • 你看到这点了吗all the view controller that open and back to root of the apps
      • 请检查下面提供的答案(MCMatan),根据 Firda 提供的代码更适合
      • @Sahzaib Qureshi 我已经这样做了,但仍然没有回到根目录
      【解决方案4】:

      你可以改变rootViewController,

      UIApplication.shared.keyWindow?.rootViewController = yourController
      

      【讨论】:

      • 它给我错误无法将类型“yourController.Type”的值分配给类型“UIViewController?”
      • YourController 这只是一个示例词,而不是在那里替换您的控制器实例。
      【解决方案5】:

      我认为在不关闭当前应用程序窗口的根视图控制器的情况下有更好的解决方案。

      将完成处理程序添加到您的方法中,当您从控制器内部调用它时,在闭包中声明完成后将被调用,您需要关闭 self(如果您通过 UINavigationController 推送控制器,只需弹出它)

      static func handleTokenInvalid(completion: @escaping () -> Void) {
          DispatchQueue.main.async {
              completion()
          }
      }
      

      然后在控制器中使用完成处理程序调用您的方法

      class ViewController: UIViewController {
      
          func call() {
              Helper.handleTokenInvalid { // this is called when you call `completion` from `handleTokenInvalid`
                  self.dismiss(animated: true)
                  //self.navigationController?.popViewController(animated: true)
              }
          }
      
      }
      

      【讨论】:

      • 我的应用程序中有很多控制器,所以我想避免更改每个控制器。是否可以在助手类中解雇?
      猜你喜欢
      • 2012-08-11
      • 2020-05-19
      • 2018-12-17
      • 1970-01-01
      • 1970-01-01
      • 2021-07-27
      • 2016-10-12
      • 2020-05-30
      • 2017-07-09
      相关资源
      最近更新 更多