I am trying to run an action for a button being pressed within a table view cell. The following code is in my table view controller class.
The button has been described as "yes" in an outlet in my class of UITableViewCell called requestsCell.
I am using Parse to save data and would like to update an object when the button is pressed. My objectIds array works fine, the cell.yes.tag also prints the correct number to the logs, however, I cannot get that number into my "connected" function in order to run my query properly.
I need a way to get the indexPath.row of the cell to find the proper 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()
}
}
}
Simple and easy way to detect button event and perform some action
We can create a closure for the button and use that in cellForRowAtIndexPath
And then in cellForRowAtIndexPath
The accepted answer using
button.tag
as information carrier which button has actually been pressed is solid and widely accepted but rather limited since a tag can only holdInt
s.You can make use of Swift's awesome closure-capabilities to have greater flexibility and cleaner code.
I recommend this article: How to properly do buttons in table view cells using Swift closures by Jure Zove.
Applied to your problem:
Declare a variable that can hold a closure in your tableview cell like
Add an action when the button is pressed that only executes the closure. You did it programmatically with
cell.yes.targetForAction("connected", withSender: self)
but I would prefer an@IBAction
outlet :-)func connected(sender: UIButton!) { ... }
as a closure tocell.tapAction = {<closure content here...>}
. Please refer to the article for a more precise explanation and please don't forget to break reference cycles when capturing variables from the environment.As Apple DOC
You can't use that method to set target for
UIButton
.Try addTarget(_:action:forControlEvents:) method
You need to add target for that button.
And of course you need to set tag of that button since you are using it.
You can achieve this by subclassing UITableViewCell. Use it in interface builder, drop a button on that cell, connect it via outlet and there you go.
EDIT: To get the tag in the connected function:
EDIT2:
This answer was provided for swift 1.2, as suggested in comments, syntax is a little different for swift 2.2.
EDIT3:
Updated for Swift 3
EDIT4:
Updated for Swift 4