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

  • iLandesiLandes Membre
    février 2017 modifié #2

    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 ! 


  • Joanna CarterJoanna Carter Membre, Modérateur
    février 2017 modifié #5

    Quand même, tu continues à  tuer des poneys !


     


    Tu dois éviter d'utiliser les "!" !!!  >:(



    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
    guard let cell = self.tableView.dequeueReusableCell(withIdentifier: "Cell") as? CustomCell else
    {
    fatalError("could not create cell")
    }

    if 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
    }

    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  ???


  • Joanna CarterJoanna Carter Membre, Modérateur

    Oh, et :


     


    5. Pourquoi utiliser 0/1 pour un drapeau booléen quand tu as Bool pour faire ça ?


  • Joanna CarterJoanna Carter Membre, Modérateur

    Et :


     


    6. Pourquoi pas ajouter le drapeau isFavoris à  ta table dans CoreData ?


  • Merci Joanna, je vais améliorer mon code avec tes remarques. 


Connectez-vous ou Inscrivez-vous pour répondre.