web-dev-qa-db-fra.com

Comment accéder au contenu d'une cellule personnalisée dans Swift à l'aide de la balise button?

J'ai une application qui a un bouton personnalisé dans une cellule personnalisée. Si vous sélectionnez la cellule, elle passe à la vue détaillée, ce qui est parfait. Si je sélectionne un bouton dans une cellule, le code ci-dessous imprime l'index de la cellule dans la console. 

J'ai besoin d'accéder au contenu de la cellule sélectionnée (à l'aide du bouton) et de les ajouter à un tableau ou à un dictionnaire. Je suis nouvelle dans ce domaine, mais je ne parviens pas à savoir comment accéder au contenu de la cellule. J'ai essayé d'utiliser didselectrowatindexpath, mais je ne sais pas comment forcer l'index à être celui de la balise ... 

Donc, fondamentalement, s'il y a 3 cellules avec 'Dog', 'Cat', 'Bird' comme cellule.repeatLabel.text dans chaque cellule et que je sélectionne les boutons des rangées 1 et 3 (index 0 et 2), ajoutez 'Dog' et 'Bird' au tableau/dictionnaire.

    // MARK: - Table View

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return postsCollection.count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell: CustomCell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomCell

    // Configure the cell...
    var currentRepeat = postsCollection[indexPath.row]
    cell.repeatLabel?.text = currentRepeat.product
    cell.repeatCount?.text = "Repeat: " + String(currentRepeat.currentrepeat) + " of " + String(currentRepeat.totalrepeat)

    cell.accessoryType = UITableViewCellAccessoryType.DetailDisclosureButton

    cell.checkButton.tag = indexPath.row;

    cell.checkButton.addTarget(self, action: Selector("selectItem:"), forControlEvents: UIControlEvents.TouchUpInside)


    return cell

}

func selectItem(sender:UIButton){

    println("Selected item in row \(sender.tag)")

 }
18
Steve Rowe

OPTION 1. Gestion avec délégation

La bonne façon de gérer les événements déclenchés à partir des sous-vues de votre cellule est d'utiliser delegation.

Pour que vous puissiez suivre les étapes:

1. Au-dessus de votre définition de classe, écrivez un protocole avec une seule méthode d'instance dans votre cellule personnalisée:

protocol CustomCellDelegate {
    func cellButtonTapped(cell: CustomCell)
} 

2. Dans votre définition de classe, déclarez une variable de délégué et appelez la méthode de protocole sur le délégué: 

var delegate: CustomCellDelegate?

@IBAction func buttonTapped(sender: AnyObject) {
    delegate?.cellButtonTapped(self)
}

3. Conformez-vous à CustomCellDelegate dans la classe où votre vue table est: 

 class ViewController: CustomCellDelegate

4. Définir le délégué de votre cellule

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as CustomCell
    cell.delegate = self

    return cell
}

5. Implémentez la méthode requise dans votre classe de contrôleur de vue. 

EDIT: Définissez d'abord un tableau vide, puis modifiez-le comme ceci:

private var selectedItems = [String]()

func cellButtonTapped(cell: CustomCell) {
    let indexPath = self.tableView.indexPathForRowAtPoint(cell.center)!
    let selectedItem = items[indexPath.row]

    if let selectedItemIndex = find(selectedItems, selectedItem) {
        selectedItems.removeAtIndex(selectedItemIndex)
    } else {
        selectedItems.append(selectedItem)
    }
}

items est un tableau défini dans mon contrôleur de vue: 

private let items = ["Dog", "Cat", "Elephant", "Fox", "Ant", "Dolphin", "Donkey", "Horse", "Frog", "Cow", "Goose", "Turtle", "Sheep"] 

OPTION 2. Traitement avec fermetures

J'ai décidé de revenir et de vous montrer une autre façon de gérer ce type de situation. L'utilisation d'une fermeture dans ce cas réduira le code et vous permettra d'atteindre votre objectif.

1. Déclarez une variable de fermeture dans votre classe de cellules:

var tapped: ((CustomCell) -> Void)?

2. Invoquez la fermeture à l'intérieur de votre gestionnaire de boutons.

@IBAction func buttonTapped(sender: AnyObject) {
    tapped?(self)
}

3. In tableView(_:cellForRowAtIndexPath:) dans la classe du contrôleur de vue contenant:

let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell       
cell.tapped = { [unowned self] (selectedCell) -> Void in
    let path = tableView.indexPathForRowAtPoint(selectedCell.center)!
    let selectedItem = self.items[path.row]

    println("the selected item is \(selectedItem)")
}
62
Vasil Garov

Comme vous avez 1 section dans la vue tableau, vous pouvez obtenir l’objet cellule comme ci-dessous.

let indexPath = NSIndexPath(forRow: tag, inSection: 0)
let cell = tableView.cellForRowAtIndexPath(indexPath) as! CustomCell!

où vous obtiendrez la balise button.

10
Amit89

Swift 3 Je viens d’obtenir une solution pour la cellule d’accès dans la fonction @IBAction en utilisant l’aperçu de la balise button.

let cell = sender.superview?.superview as! ProductCell
var intQty = Int(cell.txtQty.text!);
intQty = intQty! + 1
let  strQty = String(describing: intQty!);
cell.txtQty.text = strQty

J'ai mis à jour l'option 1 de la réponse de Vasil Garov pour Swift 3

1. Créez un protocole pour votre CustomCell:

protocol CustomCellDelegate {
    func cellButtonTapped(cell: CustomCell)
} 

2. Pour votre TableViewCell, déclarez une variable delegate et appelez la méthode de protocole correspondante: 

var delegate: CustomCellDelegate?

@IBAction func buttonTapped(sender: AnyObject) {
    delegate?.cellButtonTapped(self)
}

3. Conformez-vous à la CustomCellDelegate dans la classe où votre tableView est: 

 class ViewController: CustomCellDelegate

4. Définissez la delegate de votre cellule

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)  as CustomCell
    cell.delegate = self

    return cell
}

5. Implémentez la méthode requise dans votre ViewController

1
Herr der Töne
@IBAction func buttonTap(sender: UIButton) {
        let button = sender as UIButton
        let indexPath = self.tableView.indexPathForRowAtPoint(sender.center)!
}
1
Cao Yong

XCODE 8: Remarque importante

N'oubliez pas de définir les balises sur une valeur différente de 0.

Si vous essayez de convertir un objet avec tag = 0, cela peut fonctionner, mais dans certains cas étranges, cela ne fonctionne pas. 

Le correctif consiste à définir les balises sur différentes valeurs. J'espère que ça aide quelqu'un.

0
MLBDG

Sur la base de la réponse de Cao, voici une solution pour gérer les boutons dans une cellule de vue de collection.

    @IBAction func actionButton(sender: UIButton) {
        let point = collectionView.convertPoint(sender.center, fromView: sender.superview)
        let indexPath = collectionView.indexPathForItemAtPoint(point)
}

Sachez que l'appel de la fonction convertPoint () convertira les coordonnées du point du bouton dans l'espace d'affichage de la collection. Sans , indexPath fera toujours référence au même numéro de cellule 0

0
CyrIng