UIButton-actie in tabelweergavecel

Ik probeer een actie uit te voeren voor een knop die wordt ingedrukt in een tabelweergavecel. De volgende code bevindt zich in mijn tabelweergavecontrollerklasse.

De knop is beschreven als “ja” in een outlet in mijn klas van UITableViewCell genaamd requestsCell.

Ik gebruik Parse om gegevens op te slaan en wil een object bijwerken wanneer op de knop wordt gedrukt. Mijn objectIds-array werkt prima, de cell.yes.tag drukt ook het juiste nummer af naar de logboeken, maar ik kan dat nummer niet in mijn “verbonden” functie krijgen om mijn query correct uit te voeren.

Ik heb een manier nodig om de indexPath.row van de cel te krijgen om de juiste objectId te vinden.

   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()
        }
    }
}

Antwoord 1, autoriteit 100%

Swift 4 & Snel 5:

Je moet een doel voor die knop toevoegen.

myButton.addTarget(self, action: #selector(connected(sender:)), for: .touchUpInside)

En natuurlijk moet je de tag van die knop instellen, aangezien je hem gebruikt.

myButton.tag = indexPath.row

U kunt dit bereiken door UITableViewCell te subclasseren. Gebruik het in interfacebuilder, laat een knop op die cel vallen, sluit het aan via het stopcontact en klaar.

Om de tag in de verbonden functie te krijgen:

@objc func connected(sender: UIButton){
    let buttonTag = sender.tag
}

Antwoord 2, autoriteit 44%

Het geaccepteerde antwoord met button.tagals informatiedrager welke knop daadwerkelijk is ingedrukt, is solide en algemeen geaccepteerd, maar eerder beperkt omdat een tag alleen Ints kan bevatten.

Je kunt gebruikmaken van de geweldige sluitingsmogelijkheden van Swift voor meer flexibiliteit en schonere code.

Ik raad dit artikel aan: Hoe knoppen in tabelweergavecellen correct te gebruiken met Swift-sluitingendoor Jure Zove.

Toegepast op uw probleem:

  1. Declareer een variabele die een afsluiting kan bevatten in je tableview cellike

    var buttonTappedAction : ((UITableViewCell) -> Void)?
    
  2. Voeg een actie toe wanneer de knop wordt ingedrukt die alleen de sluiting uitvoert. Je deed het programmatisch met cell.yes.targetForAction("connected", withSender: self)maar ik heb liever een @IBActionoutlet 🙂

    @IBAction func buttonTap(sender: AnyObject) {
       tapAction?(self)
    }
    
  3. Geef nu de inhoud van func connected(sender: UIButton!) { ... }als afsluiting door aan cell.tapAction = {<closure content here...>}. Raadpleeg het artikel voor een preciezere uitleg en vergeet niet om referentiecycli te doorbreken bij het vastleggen van variabelen uit de omgeving.

Antwoord 3, autoriteit 38%

Eenvoudige en gemakkelijke manier om een ​​knopgebeurtenis te detecteren en een actie uit te voeren

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
}

Antwoord 4, autoriteit 4%

We kunnen een sluiting voor de knop maken en die gebruiken in 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)
 }
}

En dan in 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
 }

Antwoord 5, autoriteit 4%

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")
   }
}

Other episodes