UICollectionView的活动指示器

时间:2018-02-18 18:17:06

标签: ios swift firebase uicollectionview activity-indicator

我有一个从Firebase读取数据的UICollectionView,在读取​​数据时我需要某种活动指示。

我希望活动指示器在TabBar中的UICollectionView选项卡被命中时立即开始运行,我希望它停止并且一旦从Firebase加载就加载view / uicollectionView。

我看到这篇文章:

Show Activity Indicator while data load in collectionView Swift

但是我无法完全理解它,因为我不知道如何在那里集成我的UICollectionView。

编辑:

这是我从Firebase读取的代码:

self.ref = Database.database().reference()
            let loggedOnUserID = Auth.auth().currentUser?.uid


            if let currentUserID = loggedOnUserID
            {
                // Retrieve the products and listen for changes
                self.databaseHandle = self.ref?.child("Users").child(currentUserID).child("Products").observe(.childAdded, with:
                    { (snapshot) in

                        // Code to execute when new product is added
                        let prodValue = snapshot.value as? NSDictionary
                        let prodName = prodValue?["Name"] as? String ?? ""
                        let prodPrice = prodValue?["Price"] as? Double ?? -1
                        let prodDesc = prodValue?["Description"] as? String ?? ""
                        let prodURLS = prodValue?["MainImage"] as? String
                        let prodAmount = prodValue?["Amount"] as? Int ?? 0
                        let prodID = snapshot.key

                        let prodToAddToView = Product(name: prodName, price: prodPrice, currency: "NIS", description: prodDesc, location: "IL",
                                                      toSell: false, toBuy: false, owner: currentUserID, uniqueID: prodID, amount: prodAmount, mainImageURL: prodURLS)


                        self.products.append(prodToAddToView)
                        DispatchQueue.main.async
                            {
                                self.MyProductsCollection.reloadData()
                        }
                }
                ) // Closes observe function

2 个答案:

答案 0 :(得分:0)

let activityView = UIActivityIndicatorView(activityIndicatorStyle: .whiteLarge)

// waiy until main view shows 
override func viewDidAppear(_ animated: Bool) {

   super.viewDidAppear(animated)

   // create a hover view that covers all screen with opacity 0.4 to show a waiting action
    let fadeView:UIView = UIView()
    fadeView.frame = self.view.frame
    fadeView.backgroundColor = UIColor.whiteColor()
    fadeView.alpha = 0.4

   // add fade view to main view
    self.view.addSubview(fadeView)
 // add activity to main view
    self.view.addSubview(activityView)
    activityView.hidesWhenStopped = true
    activityView.center = self.view.center
// start animating activity view
    activityView.startAnimating()

  self.ref = Database.database().reference()
            let loggedOnUserID = Auth.auth().currentUser?.uid


            if let currentUserID = loggedOnUserID
            {
                // Retrieve the products and listen for changes
                self.databaseHandle = self.ref?.child("Users").child(currentUserID).child("Products").observeSingleEvent(.value, with:
                    { (snapshot) in

                        // Code to execute when new product is added
                        let prodValue = snapshot.value as? NSDictionary
                        let prodName = prodValue?["Name"] as? String ?? ""
                        let prodPrice = prodValue?["Price"] as? Double ?? -1
                        let prodDesc = prodValue?["Description"] as? String ?? ""
                        let prodURLS = prodValue?["MainImage"] as? String
                        let prodAmount = prodValue?["Amount"] as? Int ?? 0
                        let prodID = snapshot.key

                        let prodToAddToView = Product(name: prodName, price: prodPrice, currency: "NIS", description: prodDesc, location: "IL",
                                                      toSell: false, toBuy: false, owner: currentUserID, uniqueID: prodID, amount: prodAmount, mainImageURL: prodURLS)


                        self.products.append(prodToAddToView)
                        DispatchQueue.main.async
                            {
                                self.MyProductsCollection.reloadData()
                                  // remove the hover view as now we have data
                               fadeView.removeFromSuperview()
                               // stop animating the activity 
                               self.activityView.stopAnimating()
                        }
                }
                ) // Closes observe function

答案 1 :(得分:0)

我的意思是UIActivityIndicatorView并不难以使用,您在获取数据时显示它,并在完成后停止它。

private lazy var indicator : UIActivityIndicatorView = { // here we simply declaring the indicator along some properties 
    let _indicator = UIActivityIndicatorView()
    // change the color
    _indicator.color = .black
    // when you call stopAnimation on this indicator, it will hide automatically
    _indicator.hidesWhenStopped = true
    return _indicator
}()

现在您要放置它吗?您可以将其放入父视图或导航栏中。 (我选择放在navigationBar的右侧)

self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: indicator)

现在说你有这个函数从某些api返回数据(通过回调)。

// this callback emits data from a background queue
    func fetchPost(completion:@escaping(Array<Any>?, Error?) -> ()) {
        DispatchQueue.global(qos: .background).async {
           // ... do work 
             completion([], nil) // call your completionHandler based either error or data
        }
    }


/* now let's called that fetchPost function and load data into your 
  collectionView, but before let's started this indicator */


override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: indicator)
    indicator.startAnimating()

    fetchPost { [weak self] (data, err) in
        // go to the main queue to update our collectionView
        // and stop the indicator
        DispatchQueue.main.async { [weak self] in
            // stop animation
            self?.indicator.startAnimating()
            // do something we have an error
            if let _err = err {}

            if let _data = data {
                // fill array for collectionView
                // reload the collectionView
                self?.collectionView?.reloadData()
            }
        }
    }
}