Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UICollectionView的活动指示器_Ios_Swift_Firebase_Uicollectionview_Activity Indicator - Fatal编程技术网

Ios UICollectionView的活动指示器

Ios UICollectionView的活动指示器,ios,swift,firebase,uicollectionview,activity-indicator,Ios,Swift,Firebase,Uicollectionview,Activity Indicator,我有一个UICollectionView,可以从Firebase读取数据,在读取数据时我需要某种活动指示器 我希望活动指示器在点击选项卡栏中的UICollectionView选项卡后立即开始运行,并且我希望它停止,并在从Firebase加载完成后加载view/UICollectionView 我看到这个帖子: 但我不能完全理解它,因为我不知道如何在那里集成我的UICollectionView 编辑: 这是我从Firebase读取的代码: self.ref = Database.database

我有一个UICollectionView,可以从Firebase读取数据,在读取数据时我需要某种活动指示器

我希望活动指示器在点击选项卡栏中的UICollectionView选项卡后立即开始运行,并且我希望它停止,并在从Firebase加载完成后加载view/UICollectionView

我看到这个帖子:

但我不能完全理解它,因为我不知道如何在那里集成我的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

我的意思是
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
}()
现在将其放置在何处?您可以将其放置在家长的视图中,也可以放置在导航栏中。(我选择放置在导航栏的右侧)

现在假设您有一个函数(通过回调)从一些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()
            }
        }
    }
}
//此回调从后台队列发出数据
func fetchPost(完成:@转义(数组?,错误?->()){
DispatchQueue.global(qos:.background).async{
//…工作
completion([],nil)//根据错误或数据调用completionHandler
}
}
/*现在,让我们调用fetchPost函数并将数据加载到
collectionView,但在我们开始此指示器之前*/
重写func viewDidLoad(){
super.viewDidLoad()
self.navigationItem.rightBarButtonItem=UIBarButtonItem.init(customView:indicator)
指示符.startAnimating()
fetchPost{[weak self](数据,错误)位于
//转到主队列以更新我们的collectionView
//并停止指示灯
DispatchQueue.main.async{[weak self]位于
//停止动画
自我?.indicator.startAnimating()
//做点什么我们有错误
如果让_err=err{
如果让_data=data{
//collectionView的填充数组
//重新加载collectionView
self?.collectionView?.reloadData()
}
}
}
}

您不必明确了解如何将activityIndicator与collectionView集成。您必须了解在执行后台任务时如何进行UI更新。我不确定用什么替换“fetchPosts()”。我添加了代码,它似乎像以前一样工作,没有活动指示…@Sh_Khan:DispatchQueue.main.async在DispatchQueue.global之外。也许这就是为什么activityIndicator没有显示的原因。@Nitish实际上我从链接中复制了代码来说明它给他看。我编辑了我的帖子,并添加了一段我编写的代码,用于从Firebase读取。你不应该在你的lazy属性中启动activity视图。是的,我的错误@rmaddy,因为它会破坏惰性初始值设定的目的。你能给我看一下固定的代码吗?顺便说一句,看看我的编辑:)我添加了我从Firebasewhat fixed code中读取的代码片段@Ofri@Lamar你说你犯了个错误。。
self.navigationItem.rightBarButtonItem = UIBarButtonItem.init(customView: indicator)
// 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()
            }
        }
    }
}