I'm trying to fill UITableView's Cell with datas from my firestore database.
For some reasons, when i switch to the app's tab containing my tableview, i can see the good image for half a second and then it flickers to the one of the preceding cell.
Then, if i scroll down and goes back up, the good image is back but if i scroll up and down to fast, wrong images get called again.
To retrieve my datas and populate the cells i do like this:
In my class file
Retrieve the "main items" (This one works just fine)
Retrieve the details of "the sub items"
This code also include "useless" code used for testing purpose, in a hope of finding the solution..
var groupNom:String = ""
var groupStyles:String = ""
var groupHeaderImg = [StorageReference]()
var groupIconeImg = [StorageReference]()
var videosArrayed = [String]()
var groupIconeURL:String = ""
func getGroupDetails(Did: String, completion: @escaping (_ message: String) -> Void) {
let db = Firestore.firestore()
let storage = Storage.storage()
let docRef = db.collection("groups").document(Did)
docRef.getDocument { (document, error) in
if let document = document, document.exists {
self.groupNom = document.get("nom") as! String
self.groupStyles = document.get("styles") as! String
let icone_img = document.get("icone_img") as! String
self.groupIconeImg.removeAll()
self.groupIconeImg.append(storage.reference(forURL: self.StorageRefRoot + "/groups/" + document.documentID + "/icones/" + icone_img + ".png"))
//self.groupIconeURL.removeAll()
self.groupIconeURL = self.StorageRefRoot + "/groups/" + document.documentID + "/icones/" + icone_img + ".png"
//print("id: \(Did) array d'icone: \(self.groupIconeImg)")
self.groupHeaderImg.append(storage.reference(forURL:"\(self.StorageRefRoot)/groups/\(Did)/headers/\(document.get("header_img") as! String).png"))
let stylesNSArray = document.get("styles_ids") as! Array<Any>
let stylesArrayed: [String] = stylesNSArray.compactMap({ $0 as? String })
var tempGroupStyles = ""
for i in stylesArrayed.indices {
let styleDocRef = db.collection("styles_groupes").document(stylesArrayed[i])
styleDocRef.getDocument { (document, error) in
if let document = document, document.exists {
//tempBarStyles = ""
if i < stylesArrayed.count-1 { // Si c'est le dernier element, on n'ajoute pas de virgule
tempGroupStyles = "\(tempGroupStyles)\(document.get("nom") as! String), "
} else {
tempGroupStyles = "\(tempGroupStyles)\(document.get("nom") as! String)"
//print("barstyles = \(tempGroupStyles)")
}
if i == stylesArrayed.count-1 {
self.groupStyles = tempGroupStyles
}
} else {
print("style to be decrypted do not exist")
return
}
completion("done")
}
}
let videosNSArray = document.get("videos_yt_ids") as! Array<Any>
self.videosArrayed = videosNSArray.compactMap({ $0 as? String })
} else {
print("Groups details does not exist")
return
}
completion("done")
}
}
In my ViewController
This code also include "useless" code used for testing purpose, in a hope of finding the solution..
var feedAbos = abo()
var feedBars = bar()
var feedGroupes = group()
@IBOutlet weak var abosCollectionView: UICollectionView!
@IBOutlet weak var aboFeedTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated) // No need for semicolon
if Auth.auth().currentUser != nil {
//print("l'utilisateur en cours est: \(String(describing: Auth.auth().currentUser?.uid))")
feedAbos = abo()
feedAbos.getAbosFeed(uid: Auth.auth().currentUser!.uid, completion: { message in
self.aboFeedTableView.reloadData()
})
} else {
showLoginVC(viewToPresent: self, isModale: true)
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return feedAbos.feedLivesID.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView
.dequeueReusableCell(withIdentifier: "abosLivesFeedCell", for: indexPath as IndexPath) as! abosLivesFeedCell
self.feedGroupes.getGroupDetails(Did: self.feedAbos.feedGroupesID[indexPath.row], completion: { message in
if self.feedGroupes.groupIconeURL != "" {
cell.liveFeedGroupeImage.sd_setImage(with: URL(string: self.feedGroupes.groupIconeURL), placeholderImage: UIImage(named: "PLACEHOLDER1"))
} else {
cell.liveFeedGroupeImage.image = UIImage(named: "PLACEHOLDER1")
}
cell.liveFeedGroupeImage.layer.cornerRadius = 5
cell.liveFeedGroupeNomLabel?.text = self.feedAbos.feedGroupesID[indexPath.row]
})
cell.liveFeedDateLabel?.text = self.feedAbos.feedLivesDates[indexPath.row]
return cell
}
class abosLivesFeedCell: UITableViewCell {
@IBOutlet weak var liveFeedBarImage: UIImageView!
@IBOutlet weak var liveFeedGroupeImage: UIImageView!
@IBOutlet weak var liveFeedGroupeNomLabel: UILabel!
@IBOutlet weak var liveFeedDateLabel: UILabel!
@IBOutlet weak var liveFeedBarNomLabel: UILabel!
override func prepareForReuse() {
super.prepareForReuse()
self.liveFeedGroupeImage.image = nil
}
}
I think it has to do with the fact i use async data downloading. I'm thinking that maybe it has to do with the way i handle completion of my firestore classes... I also read about dispatching methods but i never used that yet.
I am pretty lost right know as it may just be something i don't know as i am definitely not a professional coder:)
Hope someone can point me in the right direction or show me where i did that stupid and very visible mistake;D
Thank you everyone !
Ok, here is what i just did to make it work. I don't think that it's the right way but it seems to work.. so..
In my ViewController i check if the Sub item's ID from the Main items' class is the same as the one retrieved from the sub items' class. If so, i load the sub items' class image into my cell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView
.dequeueReusableCell(withIdentifier: "abosLivesFeedCell", for: indexPath as IndexPath) as! abosLivesFeedCell
cell.liveFeedGroupeImage.image = UIImage(named: "PLACEHOLDER1")
self.feedGroupes.getGroupDetails(Did: self.feedAbos.feedGroupesID[indexPath.row], completion: { message in
if self.feedGroupes.groupID == self.feedAbos.feedGroupesID[indexPath.row] {
cell.liveFeedGroupeImage.sd_setImage(with: URL(string: self.feedGroupes.groupIconeURL), placeholderImage: UIImage(named: "PLACEHOLDER1"))
} else {
}
cell.liveFeedGroupeImage.layer.cornerRadius = 5
cell.liveFeedGroupeNomLabel?.text = self.feedAbos.feedGroupesID[indexPath.row]
})
cell.liveFeedDateLabel?.text = self.feedAbos.feedLivesDates[indexPath.row]
return cell
}
Hopefully one day i'll find where i am wrong. if so, i'll update the answer!
thanks everyone.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.