【问题标题】:Swift: starting and stopping the animation of an activity indicator inside a custom classSwift:在自定义类中启动和停止活动指示器的动画
【发布时间】:2017-01-16 20:29:18
【问题描述】:

我想在自定义类中放置一个活动指示器,以便可以从任何视图控制器启动/停止它。

下面的代码在启动活动指示器时工作但不停止,我该怎么做?

static func activityIndicatorFunction(view: UIView, targetVC: UIViewController, animate: Bool) {

    var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()

    if animate == false {
        activityIndicator.stopAnimating()
        UIApplication.shared.endIgnoringInteractionEvents()
    } else {
        activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
        activityIndicator.layer.cornerRadius = 6
        activityIndicator.center = targetVC.view.center
        activityIndicator.hidesWhenStopped = true
        activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
        view.addSubview(activityIndicator)
        activityIndicator.startAnimating()
        //UIApplication.shared.beginIgnoringInteractionEvents()
    }
}

启动活动指示器的示例,如果我想停止它,animate 参数将为 false。

Utils.activityIndicatorFunction(view: view, targetVC: self, animate: true)

【问题讨论】:

    标签: ios swift uiactivityindicatorview


    【解决方案1】:

    这是协议扩展的理想选择。我最近自己做了这个。

    首先在一个文件中创建协议,比如 ActivityIndi​​catorPresenter.swift

    /// Used for ViewControllers that need to present an activity indicator when loading data.
    public protocol ActivityIndicatorPresenter {
        
        /// The activity indicator
        var activityIndicator: UIActivityIndicatorView { get }
        
        /// Show the activity indicator in the view
        func showActivityIndicator()
        
        /// Hide the activity indicator in the view
        func hideActivityIndicator()
    }
    

    创建协议扩展(在同一个文件中……或不同的文件中)

    public extension ActivityIndicatorPresenter where Self: UIViewController {
        
        func showActivityIndicator() {
            DispatchQueue.main.async {
                
                self.activityIndicator.activityIndicatorViewStyle = .whiteLarge
                self.activityIndicator.frame = CGRect(x: 0, y: 0, width: 80, height: 80) //or whatever size you would like
                self.activityIndicator.center = CGPoint(x: self.view.bounds.size.width / 2, y: self.view.bounds.height / 2)
                self.view.addSubview(self.activityIndicator)
                self.activityIndicator.startAnimating()
            }
        }
        
        func hideActivityIndicator() {
            DispatchQueue.main.async {
                self.activityIndicator.stopAnimating()
                self.activityIndicator.removeFromSuperview()
            }
        }
    }
    

    然后任何视图控制器都可以符合协议

    class MyViewController: UIViewController, ActivityIndicatorPresenter {
    
    /// Make sure to add the activity indicator
    var activityIndicator = UIActivityIndicatorView()
    
    //Suppose you want to load some data from the network in this view controller
    override func viewDidLoad() {
        super.viewDidLoad()
        showActivityIndicator() //Wow you can use this here!!!
        getSomeData { data in 
            //do stuff with data
            self.hideActivityIndicator()
        }
    }
    

    【讨论】:

      【解决方案2】:

      我的建议是将它们实现为两个独立的方法,同时将它们添加到UIViewController的扩展中,如下:

      UIViewController 扩展:

      extension UIViewController {
          func showActivityIndicator() {
              let activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
              activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
              activityIndicator.layer.cornerRadius = 6
              activityIndicator.center = view.center
              activityIndicator.hidesWhenStopped = true
              activityIndicator.activityIndicatorViewStyle = .WhiteLarge
              activityIndicator.startAnimating()
              //UIApplication.shared.beginIgnoringInteractionEvents()
      
              activityIndicator.tag = 100 // 100 for example
      
              // before adding it, you need to check if it is already has been added:
              for subview in view.subviews {
                  if subview.tag == 100 {
                      print("already added")
                      return
                  }
              }
      
              view.addSubview(activityIndicator)
          }
      
          func hideActivityIndicator() {
              let activityIndicator = view.viewWithTag(100) as? UIActivityIndicatorView
              activityIndicator?.stopAnimating()
      
              // I think you forgot to remove it?
              activityIndicator?.removeFromSuperview()
      
              //UIApplication.shared.endIgnoringInteractionEvents()
          }
      }
      

      我假设您希望始终将activityIndicator 显示/隐藏到ViewController.view,如果不是,您可能需要让它成为UIView 的activityIndi​​cator 而不是UIViewController。 em>

      用法:

      例如,假设您有两个 IBAction,第一个显示活动指示器,另一个隐藏它,它们应该是这样的:

      @IBAction func show(sender: AnyObject) {
          showActivityIndicator()
      }
      
      @IBAction func hide(sender: AnyObject) {
          hideActivityIndicator()
      }
      

      【讨论】:

      • 如何使用三元运算符显示或隐藏指标?像 x = 条件? true : false,但使用 startAnimating() 和 stopAnimating()
      • @DaniSpringer 对于这种情况,您可以将这两种方法合二为一,采用Bool 参数来显示/隐藏指标,因此combinedMethod(myCondition ? true : false)
      • 啊,我明白了。在您回复之前我正在玩它并最终做了类似的事情:我将 _ 变量(不确定是否有名称)分配给一个关于是否调用一个或另一个的三元检查结果。但这很干净!谢谢
      【解决方案3】:

      我发现最好为活动指示器设置一个“标签”,然后在停止动画时引用它,使用一个功能隐藏和一个显示,如 Ahmad 建议的那样。 Ahmad F 的回答和 Guillermo 的回答似乎也不错。

      在我的 Utils.swift 文件中显示/隐藏函数:

      static func showActivityIndicator(view: UIView, targetVC: UIViewController) {
      
          var activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
      
          activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
          activityIndicator.backgroundColor = UIColor(red:0.16, green:0.17, blue:0.21, alpha:1)
          activityIndicator.layer.cornerRadius = 6
          activityIndicator.center = targetVC.view.center
          activityIndicator.hidesWhenStopped = true
          activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
          activityIndicator.tag = 1
          view.addSubview(activityIndicator)
          activityIndicator.startAnimating()
          UIApplication.shared.beginIgnoringInteractionEvents()
      }
      
      static func hideActivityIndicator(view: UIView) {
          let activityIndicator = view.viewWithTag(1) as? UIActivityIndicatorView
          activityIndicator?.stopAnimating()
          activityIndicator?.removeFromSuperview()
          UIApplication.shared.endIgnoringInteractionEvents()
      }
      

      调用显示功能:

      Utils.showActivityIndicator(view: view, targetVC: self)
      

      调用隐藏函数:

      Utils.hideActivityIndicator(view: view)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-21
        • 1970-01-01
        • 1970-01-01
        • 2017-06-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多