TableViewCell et indication que l'enregistrement existe
Bonsoir à tous,
Je vous présente mon problème.
Actuellement j'ai dans une application une liste de produit présentée dans une tableview.
L'utilisateur peut mettre en favoris des produits en faisant un swipe sur une cellule. Les favoris sont enregistrés dans un modèle Core Data (une seule entité). Lorsque le produit est déjà dans les favoris, le swipe est désactivé. Et c'est la que je rencontre un souci.
Voici ma façon de faire qui engendre des crashs de l'application :
je créé un tableau arrayFavoris :
var arrayFavoris: [Int] = []
Dans la méthode cellForRowAt :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let cell: CustomCell = self.tableView.dequeueReusableCell(withIdentifier: "Cell") as! CustomCell
let prod = (posts.object(at: (indexPath as NSIndexPath).row) as AnyObject).value(forKey: "IDProduit") as? String
let IDProd = fetchData(ID: prod!)
if IDProd > 0 {
cell.viewFavoris.backgroundColor = #colorLiteral(red: 1, green: 0.5763723254, blue: 0, alpha: 1)
}
arrayFavoris.append(IDProd)
return cell
}
fetchDate(ID: ) me renvoie 0 si le produit n'existe pas dans Core Data sinon 1.
Dans canEditRowAt, voici le code pour savoir si j'active ou non le swipe, et c'est à cet endroit que l'application crash parfois à cause du fait que l'index est en dehors des limites du tableau arrayFavoris :
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// the cells you would like the actions to appear needs to be editable
if arrayFavoris[indexPath.row] > 0 {
return false
} else {
return true
}
}
Comment vous procéderiez pour corriger ce problème?
Merci.
Réponses
Bonsoir à ta place j'utiliserai un Set plutôt qu'un Array pour stocker les index des favoris
Pour compléter la réponse de iLandes, tu pourrais même utiliser un NSMutableIndexSet (ou IndexSet en Swift) qui correspond tout à fait à ce que tu veux faire (ou ce que tu devrais faire).
Dans tableView(_:,cellForRowAt:) tu ajoutes l'index dans le set (avec insert) et dans tableView(:_,canEditRowAt:) tu peux tester l'existence de l'index dans le set avec contains.
Un des avantages d'utiliser un IndexSet c'est qu'un index ne peux apparaitre qu'une seule fois dans le set, ce qui peux ne pas être le cas dans ton code actuel puisque les index dépendant de l'appel à tableView(_:,cellForRowAt:) qui peut être appelé plusieurs fois pour un le même indexPath (suivant le défilement de la tableView ou la nécessité du recyclage des cellules).
Merci à tous les 2 ! ça fonctionne mieux comme ça !
Quand même, tu continues à tuer des poneys !
Tu dois éviter d'utiliser les "!" !!! >:(
Mais, là , je trouve quelques autres soucis.
1. Pourquoi tu écris posts.object(at:... ? Tu accèdes un NSArray que tu n'as pas créé toi-même ?
2. Pourquoi faire un cast vers NSIndexPath ?
3. Pourquoi faire un cast vers AnyObject ?
4. Pourquoi utiliser le KVC (value(forKey:... ) ?
C'est pas très Swifty ???
Oh, et :
5. Pourquoi utiliser 0/1 pour un drapeau booléen quand tu as Bool pour faire ça ?
Et :
6. Pourquoi pas ajouter le drapeau isFavoris à ta table dans CoreData ?
Merci Joanna, je vais améliorer mon code avec tes remarques.