【问题标题】:How to show activity indicator while tableView loads?如何在 tableView 加载时显示活动指示器?
【发布时间】:2015-04-28 07:22:18
【问题描述】:

当我在标签之间切换时,它会加载几秒钟,我想知道我的数据正在加载。为此,我决定添加一个活动指示器。

我写了一个小函数:

func showActivityIndicator() {
    dispatch_async(dispatch_get_main_queue()) {
        self.spinner = UIActivityIndicatorView(activityIndicatorStyle: .WhiteLarge)
        self.spinner.frame = CGRect(x: 0.0, y: 0.0, width: 80.0, height: 80.0)
        self.spinner.center = CGPoint(x:self.loadingView.bounds.size.width / 2, y:self.loadingView.bounds.size.height / 2)

        self.loadingView.addSubview(self.spinner)
        self.view.addSubview(self.loadingView)
        self.spinner.startAnimating()
    }
}

这将显示我的指标。当我从 infoController 轻按到按钮时尝试使用它:

@IBAction func goToMainFromInfo(sender: AnyObject) {
        self.showActivityIndicator()
        self.performSegueWithIdentifier("fromMainToInfoWActivity", sender: nil)
        self.hideActivityIndicator()
    }
}

我在 segue 执行之前显示它并在之后隐藏。这对我没有帮助。当我尝试使用同步时:

@IBAction func goToMainFromInfo(sender: AnyObject) {
    dispatch_async(dispatch_get_main_queue()) {
        self.showActivityIndicator()
        self.performSegueWithIdentifier("fromMainToInfoWActivity", sender: nil)
        self.hideActivityIndicator()
    }
}

但这也无济于事。当我按下选项卡时,它的不透明度变为 0.5,我在加载时等待。但我没有看到我的活动指示器。

有什么问题?

【问题讨论】:

    标签: ios uitableview swift uiactivityindicatorview


    【解决方案1】:

    试试这个:

    var indicator = UIActivityIndicatorView()
    
    func activityIndicator() {
        indicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 40, 40))
        indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
        indicator.center = self.view.center
        self.view.addSubview(indicator)    
    }
    

    你想从哪里开始制作动画

    indicator.startAnimating()
    indicator.backgroundColor = UIColor.whiteColor()
    

    停止:

    indicator.stopAnimating()
    indicator.hidesWhenStopped = true
    

    注意:避免同时调用start和stop。给个条件就好了。

    SWIFT:4.2 试试这个:

    var indicator = UIActivityIndicatorView()
    
    func activityIndicator() {
        indicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
        indicator.style = UIActivityIndicatorView.Style.gray
        indicator.center = self.view.center
        self.view.addSubview(indicator)   
    }
    

    你想从哪里开始制作动画

    activityIndicator()
    indicator.startAnimating()
    indicator.backgroundColor = .white
    

    停止:

    indicator.stopAnimating()
    indicator.hidesWhenStopped = true
    

    【讨论】:

    • 可见。只是根本没有出现
    • 为什么你给显示活动指示器并同时隐藏
    • 我评论了这行//self.hideActivityIndicator()。还是一样。不工作
    • @OrkhanAlizade 如果你想从另一个视图控制器调用活动指标意味着只需创建一个具有子类 nsobject 的类。然后将该实例调用到你的 VC。对我来说它有效如果你想要更多细节让我知道我会给出更多代码
    • @Lyuda 你能帮我在聊天中解决它吗?请!我工作了 2-3 天,一无所获!
    【解决方案2】:

    Swift 3.0

    // UIView 扩展

    fileprivate var ActivityIndicatorViewAssociativeKey = "ActivityIndicatorViewAssociativeKey"
    public extension UIView {
       var activityIndicatorView: UIActivityIndicatorView {
            get {
                if let activityIndicatorView = getAssociatedObject(&ActivityIndicatorViewAssociativeKey) as? UIActivityIndicatorView {
                    return activityIndicatorView
                } else {
                    let activityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
                    activityIndicatorView.activityIndicatorViewStyle = .gray
                    activityIndicatorView.color = .gray
                    activityIndicatorView.center = center
                    activityIndicatorView.hidesWhenStopped = true
                    addSubview(activityIndicatorView)
    
                    setAssociatedObject(activityIndicatorView, associativeKey: &ActivityIndicatorViewAssociativeKey, policy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
                    return activityIndicatorView
                }
            }
    
            set {
                addSubview(newValue)
                setAssociatedObject(newValue, associativeKey:&ActivityIndicatorViewAssociativeKey, policy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
    }
    

    // NSObject 扩展

    public extension NSObject {
        func setAssociatedObject(_ value: AnyObject?, associativeKey: UnsafeRawPointer, policy: objc_AssociationPolicy) {
            if let valueAsAnyObject = value {
                objc_setAssociatedObject(self, associativeKey, valueAsAnyObject, policy)
            }
        }
    
        func getAssociatedObject(_ associativeKey: UnsafeRawPointer) -> Any? {
            guard let valueAsType = objc_getAssociatedObject(self, associativeKey) else {
                return nil
            }
            return valueAsType
        }
    }
    

    开始动画

    tableView.activityIndicatorView.startAnimating()

    停止动画

    tableView.activityIndicatorView.stopAnimating()

    您可以在Magic找到更多代码

    【讨论】:

    • 在 Swift 4 中无法使用它自己的扩展文件。
    【解决方案3】:

    斯威夫特 2+

        class ViewController: UITableViewController {
            weak var activityIndicatorView: UIActivityIndicatorView!
    
            override func viewDidLoad() {
                super.viewDidLoad()
                let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
                tableView.backgroundView = activityIndicatorView
                self.activityIndicatorView = activityIndicatorView
                activityIndicatorView.startAnimating()
    
            }
            ...
        }
    

    【讨论】:

    • 对我来说,问题是我将它添加到视图中,该视图被我的 tableview 单元格隐藏,背景颜色与 tableview 的背景颜色相同。只要没有单元格覆盖视图,此解决方案就可以工作(因此在加载时这没问题),除非您(像我一样)有一个占位符单元格显示一些文本。在这种情况下,将加载指示器添加到该单元格可能会更容易。
    【解决方案4】:

    我使用两种扩展方法来添加一个UIActivityIndicatorView 作为tableview 的backgroundView

    extension UITableView {
        func showActivityIndicator() {
            DispatchQueue.main.async {
                let activityView = UIActivityIndicatorView(style: .medium)
                self.backgroundView = activityView
                activityView.startAnimating()
            }
        }
    
        func hideActivityIndicator() {
            DispatchQueue.main.async {
                self.backgroundView = nil
            }
        }
    }
    

    你可以这样显示/隐藏它。

    tableView.showActivityIndicator()
    tableView.hideActivityIndicator()
    

    【讨论】:

      【解决方案5】:

      这段代码可以帮助你:)

         let indicator:UIActivityIndicatorView = UIActivityIndicatorView  (activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray) 
         indicator.color = UIColor .magentaColor()
         indicator.frame = CGRectMake(0.0, 0.0, 10.0, 10.0)
         indicator.center = self.view.center
         self.view.addSubview(indicator)
         indicator.bringSubviewToFront(self.view)
         indicator.startAnimating()
      

      【讨论】:

        【解决方案6】:

        SWIFT

        把它放在你的班级下面:

        let indicator:UIActivityIndicatorView = UIActivityIndicatorView  (activityIndicatorStyle: UIActivityIndicatorViewStyle.Gray)
        

        把它放在你的 loadView() 中:

        indicator.color = UIColor .magentaColor()
        indicator.frame = CGRectMake(0.0, 0.0, 10.0, 10.0)
        indicator.center = self.view.center
        self.view.addSubview(indicator)
        indicator.bringSubviewToFront(self.view)
        indicator.startAnimating()
        

        在我的例子中,我通过 func 请求请求 json 对象,所以我将它放在该函数的末尾,以便在数据加载后删除活动指示器:

        self.indicator.stopAnimating()
        self.indicator.hidesWhenStopped = true
        

        【讨论】:

          【解决方案7】:

          另一种方法,在我的代码中,我为 UITableView (Swift 2.3) 添加了一个扩展:

          extension UITableView {
              func activityIndicator(center: CGPoint = CGPointZero, loadingInProgress: Bool) {
                  let tag = 12093
                  if loadingInProgress {
                      var indicator = UIActivityIndicatorView()
                      indicator = UIActivityIndicatorView(frame: CGRectMake(0, 0, 40, 40))
                      indicator.tag = tag
                      indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.WhiteLarge
                      indicator.color = //Your color here
                      indicator.center = center
                      indicator.startAnimating()
                      indicator.hidesWhenStopped = true
                      self.superview?.addSubview(indicator)
                  }else {
                       if let indicator = self.superview?.viewWithTag(tag) as? UIActivityIndicatorView { {
                          indicator.stopAnimating()
                          indicator.removeFromSuperview()
                      }
                  }
              }
          }
          

          注意:我的 tableview 嵌入在 UIView(superview)中

          【讨论】:

            【解决方案8】:
             func setupSpinner(){
                spinner = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height:40))
                spinner.color = UIColor(Colors.Accent)
                self.spinner.center = CGPoint(x:UIScreen.main.bounds.size.width / 2, y:UIScreen.main.bounds.size.height / 2)
                self.view.addSubview(spinner)
                spinner.hidesWhenStopped = true
            }
            

            【讨论】:

              【解决方案9】:

              更新 Swift 4.2:

              1.调用viewDidLoad上的activityIndi​​cator函数
              例如:

              var indicator = UIActivityIndicatorView()
              override func viewDidLoad() {
                  //Initializing the Activity Indicator
                  activityIndicator()
                  //Starting the Activity Indicator
                  indicator.startAnimating()
                  //Call Your WebService or API
                  callAPI()
              }
              

              这里是添加 ActivityIndi​​cator 作为子视图的代码

              func activityIndicator() {
                          indicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
                          indicator.style = UIActivityIndicatorView.Style.whiteLarge
                          indicator.color = .red
                          indicator.center = self.view.center
                          self.view.addSubview(indicator)
                  }
              

              2。执行 UI 相关操作或 API 调用并停止活动指示器

                  func callAPI() {     
                      YourModelClass.fetchResult(someParams, 
                      completionHandler: { (response) in 
                      //Do necessary UIUpdates
                      //And stop Activity Indicator
                      self.indicator.stopAnimating()
                      })
                  }
              

              【讨论】:

                【解决方案10】:

                使用“惰性变量”。比功能好

                fileprivate lazy var activityIndicatorView: UIActivityIndicatorView = {
                    let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .gray)
                    activityIndicatorView.hidesWhenStopped = true
                
                    // Set Center
                    var center = self.view.center
                    if let navigationBarFrame = self.navigationController?.navigationBar.frame {
                        center.y -= (navigationBarFrame.origin.y + navigationBarFrame.size.height)
                    }
                    activityIndicatorView.center = center
                
                    self.view.addSubview(activityIndicatorView)
                    return activityIndicatorView
                }()
                

                在任何地方启动微调器

                喜欢这个

                func requestData() {
                  // Request something
                  activityIndicatorView.startAnimating()
                }
                

                【讨论】:

                  【解决方案11】:

                  @brocolli 对 swift 4.0 的回答。在获取或设置关联对象之前,您必须使用 objc_。根据文档,在 Swift 中获取和设置关联对象的 API 是:

                  func objc_getAssociatedObject(object: AnyObject!,
                                                   key: UnsafePointer<Void>
                                               )  -> AnyObject!
                  
                  func objc_setAssociatedObject(object: AnyObject!,
                                                   key: UnsafePointer<Void>,
                                                 value: AnyObject!,
                                                policy: objc_AssociationPolicy)
                  

                  实施:

                  import UIKit
                  
                  fileprivate var ActivityIndicatorViewAssociativeKey = "ActivityIndicatorViewAssociativeKey"
                  
                  extension UIView {
                      var activityIndicatorView: UIActivityIndicatorView {
                          get {
                              if let activityIndicatorView = objc_getAssociatedObject(self, &ActivityIndicatorViewAssociativeKey) as? UIActivityIndicatorView {
                                  return activityIndicatorView
                              } else {
                                  let activityIndicatorView = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
                                  activityIndicatorView.activityIndicatorViewStyle = .gray
                                  activityIndicatorView.color = .gray
                                  activityIndicatorView.center = center
                                  activityIndicatorView.hidesWhenStopped = true
                                  addSubview(activityIndicatorView)
                  
                                  objc_setAssociatedObject(self, &ActivityIndicatorViewAssociativeKey, activityIndicatorView, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
                                  return activityIndicatorView
                              }
                          }
                  
                          set {
                              addSubview(newValue)
                              objc_setAssociatedObject(self, &ActivityIndicatorViewAssociativeKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
                          }
                  
                      }
                  }
                  

                  【讨论】:

                  • 请提供一些关于如何解决问题的详细信息。否则,此答案对未来的用户几乎毫无用处。
                  【解决方案12】:

                  为了将 UIActivityIndi​​cator 放在前台,甚至在最终的 UITableViewController 分隔符上,我采用了这个解决方案。

                  • 我以编程方式添加了 UIActivityIndi​​cator,并将其添加为我的 UINavigationController 的子视图

                    var activityIndicator: UIActivityIndicatorView!
                    
                    override func viewDidLoad() {
                       super.viewDidLoad()
                       // Code
                       // .... omissis
                    
                       // Set activity indicator
                       activityIndicator = UIActivityIndicatorView(style: .whiteLarge)
                       activityIndicator.color = UIColor.darkGray
                       activityIndicator.center = tableView.center
                       activityIndicator.hidesWhenStopped = true
                       activityIndicator.stopAnimating()
                       self.navigationController?.view.addSubview(activityIndicator)
                    }
                    
                  • 我只是在需要时启动和停止它(在我的情况下):

                    func animateActivityIndicator(_ sender: Any ) {
                       guard let vc = sender as? UIViewController else { return }
                       if let v = vc as? MyTableViewController {
                           if v.activityIndicator.isAnimating {
                               v.activityIndicator.stopAnimating()
                           } else {
                               v.activityIndicator.startAnimating()
                           }
                       }
                       // Others UIViewController or UITableViewController follows...
                       // all of them exhibits an activityIndicator variable
                       // implemented programmatically or with the storyboard
                    }
                    

                  PS。我的环境是 Xcode 10.0,iOS 12.0

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多