我有一个从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
答案 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()
}
}
}
}