如何从appDelegate访问每个ViewController?

时间:2018-07-25 06:03:36

标签: ios swift alamofire viewcontroller appdelegate

我的问题是我正在使用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视图而不是<#T ## UIView#>! ?? ? 此框架的用法是,您在appDelegate中键入一行,并且它是每个网络请求的观察者:

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

4 个答案:

答案 0 :(得分:1)

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

请使用此代码从应用程序中的任何位置获取最后一个Viewcontroller

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

答案 1 :(得分:1)

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

https://github.com/SVProgressHUD/SVProgressHUD

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

pod'SVProgressHUD'

第二,将SVProgressHUD安装到您的项目中:

pod安装

将以下行添加到您的Podfile中:

use_frameworks!

就这样,现在您可以使用其方法导入SVProgressHUD了。

检查下面的图像以供参考。

enter image description here

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

  1. 要导入SVProgressHUD
  2. 在进行任何网络呼叫之前,像SVProgressHUD.show()一样使用
  3. 在完成回调中像SVProgressHUD.dismiss()一样使用。

答案 2 :(得分:1)

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

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

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

添加以下内容以撤消:

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

现在在每个控制器中(如果您有Super View控制器,则会更容易):

  • 在viewWillAppear中:

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)

  • 在viewWillDisappear中

    NotificationCenter.default.removeObserver(self)

答案 3 :(得分:0)

如果我理解您的问题正确,那么您需要一个当前的可见视图控制器,并希望在其上添加自定义视图以在该特定视图中显示为活动指示器。因此,首先需要在AppDelegate中获得带有以下代码的顶视图控制器:

func getTopViewController() -> UIViewController {

    var viewController = UIViewController()

    if let vc =  UIApplication.shared.delegate?.window??.rootViewController {

        viewController = vc
        var presented = vc

        while let top = presented.presentedViewController {
            presented = top
            viewController = top
        }
    }

    return viewController
}

之后,创建一个要显示在该顶视图控制器上方的视图控制器,并根据您的要求添加以下代码(例如,在此未创建Internet视图控制器):

let topViewController = self.getTopViewController()
        if topViewController is UINavigationController {
            let topViewController = (self.getTopViewController() as! UINavigationController).topViewController
            let storyboard = UIStoryboard(name: "NoInternet", bundle: nil)
            let vc = storyboard.instantiateViewController(withIdentifier: "NoInternetViewController") as! NoInternetViewController
            topViewController?.present(vc, animated: true, completion: nil)
        } else {
            let storyboard = UIStoryboard(name: "NoInternet", bundle: nil)
            let vc = storyboard.instantiateViewController(withIdentifier: "NoInternetViewController") as! NoInternetViewController
            topViewController.present(vc, animated: true, completion: nil)
        }

,您可以通过以下方式关闭它:

let topViewController = self.getTopViewController()
topViewController.dismiss(animated: true, completion: nil)

希望这会有所帮助。