2017-09-03 13 views
0

J'ai une fonction dans un protocole qui prend un TableViewcell comme argument.Comment puis-je empêcher ma cellule tableView de réutiliser le bouton à l'intérieur?

protocol GoingButtonDelegate { 
    func goingButtonPressed(cell: TableViewCell) 
} 

class TableViewCell: UITableViewCell { 
    // Outlets 
    @IBOutlet weak var goingButton: UIButton! 

    var delegate: GoingButtonDelegate? 

    @IBAction func goingButtonTapped(_ sender: Any) { 
     delegate?.goingButtonPressed(cell: self) 
    } 

Je puis aller à mon ViewController et mettent en place le délégué et sa fonction, qui est de changer l'image d'un bouton quand on tape dessus. Le "goingSelected" est une image verte et le "goingDeselected" est une image rouge.

Tout cela fonctionne très bien, lorsque vous appuyez sur le bouton d'une cellule passe du rouge au vert et vice versa. Cependant, lorsque la cellule est réutilisée, l'état du bouton de la cellule persiste et est réutilisé pour la nouvelle ligne qui entre dans la vue. Y at-il moyen d'empêcher que cela ne se produise?

extension ViewController: GoingButtonDelegate { 
    func goingButtonPressed(cell: TableViewCell) { 
     cell.goingButton.isSelected = !cell.goingButton.isSelected 

     if cell.goingButton.isSelected == true { 
      cell.goingButton.setImage(UIImage(named: "goingSelected"), for: UIControlState.selected) 
     } else if cell.goingButton.isSelected == false { 
      cell.goingButton.setImage(UIImage(named: "goingDeselected"), for: UIControlState.normal) 
     } 
    } 
} 
+1

double possible de [Comment éviter UITableView de cellules réutilisation personnalisées Swift] (https://stackoverflow.com/ questions/37938809/how-to-prevent-uitableview-from-réutilisation-custom-cells-swift) –

+0

Vous ne voulez pas éviter de réutiliser des cellules. Ce n'est pas la bonne solution. – rmaddy

Répondre

0

Il est possible

vient remplacer

let cell = tableView.dequeueReusableCell(withIdentifier: identifier, 
    for: indexPath) 

avec:

let cell= Bundle.main.loadNibNamed(identifier, owner: self, options: nil)?[0] 

mais je pense que vous avez besoin de changer votre logique d'application.

Set Images à l'intérieur de votre classe de cellules

class TableViewCell: UITableViewCell { 
    override func awakeFromNib() { 
    super.awakeFromNib() 
    self.goingButton.setImage(UIImage(named: "goingDeselected"), for:.normal) 
    self.goingButton.setImage(UIImage(named: "goingSelected"), for:.selected) 
    } 
} 

et méthode goingButtonPressed(cell: TableViewCell) changement cell à votre objet et juste définir Bool de type vrai ou faux

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    ... 
    cell.goingButton.isSelected = object.isSelected 
    ... 
} 
+1

Vous ne voulez pas faire cela. N'évitez pas de réutiliser des cellules. – rmaddy

+0

@rmaddy Je réponds déjà que la logique du changement sera meilleure –

0

Vous devez stocker les lignes sélectionnées dans un tableau de chemins d'index, avant cela, je pense que vous devriez faire quelques améliorations ... ou beaucoup !!

la cellule elle-même devrait gérer son bouton, le contrôleur devrait simplement garder une trace de l'état de toutes les cellules. Ajoutez ces deux propriétés à votre cellule

class TableViewCell: UITableViewCell { 
    var indexPath:IndexPath? 
    var isSelected : Bool = false { 
     didSet{ 
      if isSelected { 
       cell.goingButton.setImage(UIImage(named: "goingSelected"), for: UIControlState.normal) 
      } else { 
       cell.goingButton.setImage(UIImage(named: "goingDeselected"), for: UIControlState.normal) 
      } 
     } 
    } 
    // Outlets 
    @IBOutlet weak var goingButton: UIButton! 

    var delegate: GoingButtonDelegate? 

    @IBAction func goingButtonTapped(_ sender: Any) { 
     self.isSelected = !self.isSelected 
     delegate?.goingButtonPressed(cell: self) 
    } 
    .. 
    ... 
} 

et stocker les cellules sélectionnées dans votre contrôleur de vue de garder une trace de chaque état de la cellule.

extension ViewController: GoingButtonDelegate { 
    var selectedCells = NSMutableArray() 
    func goingButtonPressed(cell: TableViewCell) { 
     if cell.isSelected { 
      selectedCells.add(cell.indexPath) 
     } else { 
      selectedCells.remove(cell.indexPath) 
     } 
    } 
} 

et dans votre « cellule pour la ligne » méthode juste ajouter un petit changement

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier") as! TableViewCell 
    cell.indexPath = indexPath 
    cell.isSelected = selectedCells.contains(indexPath) 
    .. 
    ... 
    return cell 
}