J'essaie d'exécuter une action pour un bouton enfoncé dans une cellule de la vue tableau. Le code suivant est dans ma classe de contrôleur de vue de table.
Le bouton a été décrit comme "oui" dans une prise de ma classe UITableViewCell appelée "requestCell".
J'utilise Parse pour enregistrer des données et souhaite mettre à jour un objet lorsque le bouton est enfoncé. Mon tableau objectIds fonctionne bien, cell.yes.tag imprime également le numéro correct dans les journaux. Cependant, je ne peux pas obtenir ce numéro dans ma fonction "connecté" afin d'exécuter correctement ma requête.
J'ai besoin d'un moyen d'obtenir le chemin indexPath.row de la cellule pour trouver le bon objectId.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as requestsCell
// Configure the cell...
cell.name.text = requested[indexPath.row]
imageFiles[indexPath.row].getDataInBackgroundWithBlock{
(imageData: NSData!, error: NSError!) -> Void in
if error == nil {
let image = UIImage(data: imageData)
cell.userImage.image = image
}else{
println("not working")
}
}
cell.yes.tag = indexPath.row
cell.yes.targetForAction("connected", withSender: self)
println(cell.yes.tag)
return cell
}
func connected(sender: UIButton!) {
var query = PFQuery(className:"Contacts")
query.getObjectInBackgroundWithId(objectIDs[sender.tag]) {
(gameScore: PFObject!, error: NSError!) -> Void in
if error != nil {
NSLog("%@", error)
} else {
gameScore["connected"] = "yes"
gameScore.save()
}
}
}
Vous devez ajouter une cible pour ce bouton.
myButton.addTarget(self, action: "connected:", forControlEvents: .TouchUpInside)
Et bien sûr, vous devez définir la balise de ce bouton puisque vous l'utilisez.
myButton.tag = indexPath.row
Vous pouvez y parvenir en sous-classant UITableViewCell. Utilisez-le dans le constructeur d’interface, déposez un bouton sur cette cellule, connectez-le via la sortie et le tour est joué.
EDIT: Pour obtenir le tag dans la fonction connectée:
func connected(sender: UIButton){
let buttonTag = sender.tag
}
EDIT2:
Cette réponse a été fournie pour Swift 1.2, comme suggéré dans les commentaires, la syntaxe est légèrement différente pour Swift 2.2.
myButton.addTarget(self, action: #selector(ClassName.FunctionName(_:), forControlEvents: .TouchUpInside)
EDIT3:
Mis à jour pour Swift 3
myButton.addTarget(self, action: #selector(ClassName.FunctionName.buttonTapped), for: .touchUpInside)
EDIT4:
Mis à jour pour Swift 4
@objc func connected(sender: UIButton){
let buttonTag = sender.tag
}
La réponse acceptée en utilisant button.tag
comme support d’information sur lequel le bouton a été actionné est solide et largement acceptée, mais plutôt limitée puisqu'un tag peut uniquement contenir Int
s.
Vous pouvez utiliser les capacités de fermeture impressionnantes de Swift pour obtenir une plus grande flexibilité et un code plus propre.
Je recommande cet article: Comment faire correctement des boutons dans les cellules de la vue tableau à l'aide de fermetures Swift de Jure Zove.
Appliqué à votre problème:
Déclarez une variable pouvant contenir une fermeture dans votre tableview cell comme
var buttonTappedAction : ((UITableViewCell) -> Void)?
Ajoutez une action lorsque vous appuyez sur le bouton qui n’exécute que la fermeture. Vous l'avez fait par programme avec cell.yes.targetForAction("connected", withSender: self)
mais je préférerais une sortie @IBAction
:-)
@IBAction func buttonTap(sender: AnyObject) {
tapAction?(self)
}
func connected(sender: UIButton!) { ... }
comme fermeture à cell.tapAction = {<closure content here...>}
. Veuillez vous reporter à l'article pour une explication plus précise et n'oubliez pas de rompre les cycles de référence lors de la capture de variables de l'environnement.Un moyen simple et facile de détecter un événement de bouton et d'effectuer une action
class youCell: UITableViewCell
{
var yourobj : (() -> Void)? = nil
//You can pass any kind data also.
//var user: ((String?) -> Void)? = nil
override func awakeFromNib()
{
super.awakeFromNib()
}
@IBAction func btnAction(sender: UIButton)
{
if let btnAction = self.yourobj
{
btnAction()
// user!("pass string")
}
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = youtableview.dequeueReusableCellWithIdentifier(identifier) as? youCell
cell?.selectionStyle = UITableViewCellSelectionStyle.None
cell!. yourobj =
{
//Do whatever you want to do when the button is tapped here
self.view.addSubview(self.someotherView)
}
cell.user = { string in
print(string)
}
return cell
}
Nous pouvons créer une fermeture pour le bouton et l'utiliser dans cellForRowAtIndexPath
class ClosureSleeve {
let closure: () -> ()
init(attachTo: AnyObject, closure: @escaping () -> ()) {
self.closure = closure
objc_setAssociatedObject(attachTo, "[\(arc4random())]", self,.OBJC_ASSOCIATION_RETAIN)
}
@objc func invoke() {
closure()
}
}
extension UIControl {
func addAction(for controlEvents: UIControlEvents = .primaryActionTriggered, action: @escaping () -> ()) {
let sleeve = ClosureSleeve(attachTo: self, closure: action)
addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
}
}
Et puis dans cellForRowAtIndexPath
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = youtableview.dequeueReusableCellWithIdentifier(identifier) as? youCell
cell?.selectionStyle = UITableViewCell.SelectionStyle.none//Swift 4 style
button.addAction {
//Do whatever you want to do when the button is tapped here
print("button pressed")
}
return cell
}
class TableViewCell: UITableViewCell {
@IBOutlet weak var oneButton: UIButton!
@IBOutlet weak var twoButton: UIButton!
}
class TableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell
cell.oneButton.addTarget(self, action: #selector(TableViewController.oneTapped(_:)), for: .touchUpInside)
cell.twoButton.addTarget(self, action: #selector(TableViewController.twoTapped(_:)), for: .touchUpInside)
return cell
}
func oneTapped(_ sender: Any?) {
print("Tapped")
}
func twoTapped(_ sender: Any?) {
print("Tapped")
}
}
En tant que Apple DOC
targetForAction: withSender:
Renvoie l'objet cible auquel répond une action.
Vous ne pouvez pas utiliser cette méthode pour définir la cible pour UIButton
.
Essayez addTarget (_: action: forControlEvents :) method
dans Swift 4
dans cellForRowAt indexPath:
cell.prescriptionButton.addTarget(self, action: Selector("onClicked:"), for: .touchUpInside)
fonction exécutée après que l'utilisateur a appuyé sur le bouton:
@objc func onClicked(sender: UIButton){
let tag = sender.tag
}