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.tag
als informatiedrager welke knop daadwerkelijk is ingedrukt, is solide en algemeen geaccepteerd, maar eerder beperkt omdat een tag alleen Int
s 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:
-
Declareer een variabele die een afsluiting kan bevatten in je tableview cellike
var buttonTappedAction : ((UITableViewCell) -> Void)?
-
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@IBAction
outlet 🙂@IBAction func buttonTap(sender: AnyObject) { tapAction?(self) }
- Geef nu de inhoud van
func connected(sender: UIButton!) { ... }
als afsluiting door aancell.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")
}
}