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)")
}
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)
}
}
où 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)")
}
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.
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
.
@IBAction func buttonTap(sender: UIButton) {
let button = sender as UIButton
let indexPath = self.tableView.indexPathForRowAtPoint(sender.center)!
}
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.
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