如何从 appDelegate 访问每个 ViewController?

Posted

技术标签:

【中文标题】如何从 appDelegate 访问每个 ViewController?【英文标题】:How to access every ViewController from appDelegate? 【发布时间】:2018-07-25 06:03:35 【问题描述】:

我的问题是我正在使用 Alamofire,我从以下位置添加了 AlamofireActivityIndi​​cator: AlamofireNetworkActivityIndicator GitHub

我的问题是如何将视图添加到该用户所在的 viewController 并进行网络请求,该视图显示指示器而不是在状态栏中显示指示器!

我有一个问题,我将框架代码更改为:

AlamofireNetworkActivityIndi​​cator 框架的原始代码:

private var activityIndicatorState: ActivityIndicatorState = .notActive 
    didSet 
        switch activityIndicatorState 
        case .notActive:
            isNetworkActivityIndicatorVisible = false
            invalidateStartDelayTimer()
            invalidateCompletionDelayTimer()
        case .delayingStart:
            scheduleStartDelayTimer()
        case .active:
            invalidateCompletionDelayTimer()
            isNetworkActivityIndicatorVisible = true
        case .delayingCompletion:
            scheduleCompletionDelayTimer()
        
    

我已经添加了两个方法来创建和删除屏幕中心 50*50 的红色视图,稍后我将对其进行自定义以显示指示器

fileprivate func myIndicatorView (superView:UIView) 
    let view = UIView.init()
    view.tag = 2018
    view.backgroundColor = .red
    superView.addSubview(view)
    view.frame = CGRect(x: UIScreen.main.bounds.midX-25,
                        y: UIScreen.main.bounds.midY-25,
                        width: 50,
                        height: 50)


fileprivate func removeIndicatorView (superView:UIView) 
    superView.subviews.forEach (myView) in
        if myView.tag == 2018 
            myView.removeFromSuperview()
        
    

,但现在我的问题在这里:

private var activityIndicatorState: ActivityIndicatorState = .notActive 
    didSet 
        switch activityIndicatorState 
        case .notActive:
            self.myIndicatorView(superView: <#T##UIView#>)
            isNetworkActivityIndicatorVisible = false
            invalidateStartDelayTimer()
            invalidateCompletionDelayTimer()
        case .delayingStart:
            scheduleStartDelayTimer()
        case .active:
            self.removeIndicatorView(superView: <#T##UIView#>)
            invalidateCompletionDelayTimer()
            isNetworkActivityIndicatorVisible = true
        case .delayingCompletion:
            scheduleCompletionDelayTimer()
        
    

问题:

如何定义 ViewControllers 视图而不是 ! ?? ? 这个框架的用法是你在 appDelegate 中输入一行,它会观察每个网络请求:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
    NetworkActivityIndicatorManager.shared.isEnabled = true
    return true

【问题讨论】:

你基本上想问什么不清楚? @vivekDas 在 [问题:] 部分我问过!如何将任何 ViewControllers 视图添加到 appDelegate 中的自定义类 如何将任何 ViewControllers 视图添加到 appDelegate 的自定义类中?你这是什么意思?你想达到什么目标? @vivekDas 我想根据网络请求时间为每个网络请求添加视图! 你想显示网络调用的活动指示器视图吗? 【参考方案1】:

您应该使用通知模式广播一条消息,而不是尝试到达特定控制器。

添加以下行以发送“添加加载程序消息”

NotificationCenter.default.post(name: Notification.Name(rawValue: "AddLoader", object: nil)

添加以下内容以关闭:

NotificationCenter.default.post(name: Notification.Name(rawValue: "HideLoader", object: nil)

现在在每个控制器中(如果你有 Super 视图控制器更容易):

在视图中将出现:

NotificationCenter.default.addObserver(self, selector: #selector(yourShowSelector), name: Notification.Name(rawValue: "AddLoader"), object: nil) NotificationCenter.default.addObserver(self, selector: #selector(yourHide Selector), name: NSNotification.Name(rawValue: "HideLoader"), object: nil)

在视图中将消失

NotificationCenter.default.removeObserver(self)

【讨论】:

太棒了!!你摇滚\m/【参考方案2】:

因此,如果您使用的是 CocoaPods,那么您可以在项目中轻松使用 SVProgressHUD 来显示活动指示器。检查以下链接

https://github.com/SVProgressHUD/SVProgressHUD

首先,将以下行添加到您的 Podfile:

pod 'SVProgressHUD'

其次,将 SVProgressHUD 安装到您的项目中:

pod 安装

将以下行添加到您的 Podfile:

使用框架!

就是这样,现在您可以导入 SVProgressHUD 并使用它的方法。

查看下面的图片以供参考。

成功完成上述过程后,只需执行以下操作:

    导入 SVProgressHUD 在进行任何网络调用之前像 SVProgressHUD.show() 一样使用 在完成回调中使用类似 SVProgressHUD.dismiss()。

【讨论】:

如何使用这个框架?我应该在哪里启用这个? 现在编辑了ans请检查。【参考方案3】:

你的问题不清楚。但我认为您想从用户进行网络请求的位置获取您的最后一个控制器。

请使用此代码从应用程序的任何位置获取最后一个视图控制器

extension UIApplication 

  class func topViewController(_ base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? 
      if let nav = base as? UINavigationController 
         return topViewController(nav.visibleViewController)
      
      if let tab = base as? UITabBarController 
         if let selected = tab.selectedViewController 
            return topViewController(selected)
         
      
      if let presented = base?.presentedViewController 
        return topViewController(presented)
      
      return base
   

【讨论】:

以上是关于如何从 appDelegate 访问每个 ViewController?的主要内容,如果未能解决你的问题,请参考以下文章

无法从相关的 View Controller 访问 appdelegate 实例变量

如何从 AppDelegate 上的 TabBarController 获取 ViewController?

Swift UI - 如何从外部访问 @State 变量?

如何从 AppDelegate.m 访问 tabBarController?

如何从 AppDelegate 访问 ViewController 变量

如何从 appdelegate 访问 uitablviews 选定项目?