Ich versuche, eine Aktion für eine Schaltfläche auszuführen, die in einer Tabellenzellenzelle gedrückt wird. Der folgende Code befindet sich in meiner Tabellensicht-Controller-Klasse.
Die Schaltfläche wurde in einem Outlet in meiner Klasse von UITableViewCell mit dem Namen requestCell als "yes" beschrieben.
Ich verwende Parse, um Daten zu speichern, und möchte ein Objekt aktualisieren, wenn die Schaltfläche gedrückt wird. Mein objectIds-Array funktioniert einwandfrei. Der cell.yes.tag gibt auch die richtige Nummer in die Protokolle aus. Ich kann diese Nummer jedoch nicht in meine "Connected" -Funktion aufnehmen, um meine Abfrage ordnungsgemäß auszuführen.
Ich brauche einen Weg, um die indexPath.row der Zelle zu finden, um die richtige objectId zu finden.
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()
}
}
}
Sie müssen ein Ziel für diese Schaltfläche hinzufügen.
myButton.addTarget(self, action: "connected:", forControlEvents: .TouchUpInside)
Und natürlich müssen Sie das Tag dieser Schaltfläche festlegen, da Sie es verwenden.
myButton.tag = indexPath.row
Sie können dies erreichen, indem Sie UITableViewCell subclassing. Verwenden Sie es im Interface Builder, lassen Sie einen Knopf auf diese Zelle fallen, verbinden Sie es über eine Steckdose und los geht's.
EDIT: Um das Tag in der verbundenen Funktion zu erhalten:
func connected(sender: UIButton){
let buttonTag = sender.tag
}
EDIT2:
Diese Antwort wurde für Swift 1.2 bereitgestellt. Wie in Kommentaren vorgeschlagen, unterscheidet sich die Syntax für Swift 2.2 etwas.
myButton.addTarget(self, action: #selector(ClassName.FunctionName(_:), forControlEvents: .TouchUpInside)
EDIT3:
Aktualisiert für Swift 3
myButton.addTarget(self, action: #selector(ClassName.FunctionName.buttonTapped), for: .touchUpInside)
EDIT4:
Aktualisiert für Swift 4
@objc func connected(sender: UIButton){
let buttonTag = sender.tag
}
Die akzeptierte Antwort, die button.tag
als Informationsträger verwendet, wobei die Schaltfläche tatsächlich gedrückt wurde, ist solide und allgemein akzeptiert, jedoch eher begrenzt, da ein Tag nur Int
s enthalten kann.
Sie können die hervorragenden Schließfunktionen von Swift nutzen, um mehr Flexibilität und sauberen Code zu erhalten.
Ich empfehle diesen Artikel: Wie man Schaltflächen in Tabellensichtzellen mit Swift-Verschlüssen richtig ausführt von Jure Zove.
Auf Ihr Problem angewendet:
Deklarieren Sie eine Variable, die eine Schließung in Ihrer Tabellenansicht cell wie .__ enthalten kann.
var buttonTappedAction : ((UITableViewCell) -> Void)?
Fügen Sie eine Aktion hinzu, wenn die Taste gedrückt wird und nur das Schließen ausgeführt wird. Sie haben es programmgesteuert mit cell.yes.targetForAction("connected", withSender: self)
gemacht, aber ich würde einen @IBAction
-Ausgang bevorzugen :-)
@IBAction func buttonTap(sender: AnyObject) {
tapAction?(self)
}
func connected(sender: UIButton!) { ... }
an cell.tapAction = {<closure content here...>}
. Eine genauere Erklärung finden Sie in dem Artikel. Vergessen Sie nicht, Referenzzyklen beim Erfassen von Variablen aus der Umgebung zu unterbrechen.Einfache und einfache Möglichkeit, Schaltflächenereignisse zu erkennen und Aktionen auszuführen
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
}
Wir können einen Abschluss für die Schaltfläche erstellen und diesen in cellForRowAtIndexPath verwenden
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)
}
}
Und dann 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
}
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")
}
}
Als Apple DOC
targetForAction: withSender:
Gibt das Zielobjekt zurück, das auf .__ antwortet. eine Handlung.
Sie können diese Methode nicht verwenden, um das Ziel für UIButton
festzulegen.
Versuchen Sie addTarget (_: action: forControlEvents :)
Mit Swift 5 hat das bei mir funktioniert !!
Schritt 1. IBOutlet für UIButton in My CustomCell.Swift erstellt
class ListProductCell: UITableViewCell {
@IBOutlet weak var productMapButton: UIButton!
//todo
}
Schritt 2. In der CellForRowAtIndex-Methode wurde eine Aktionsmethode hinzugefügt, und die Methodenimplementierung wurde im selben Ansichtscontroller bereitgestellt
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListProductCell") as! ListProductCell
cell.productMapButton.addTarget(self, action: #selector(ListViewController.onClickedMapButton(_:)), for: .touchUpInside)
return cell
}
@objc func onClickedMapButton(_ sender: Any?) {
print("Tapped")
}
in Swift 4
in cellForRowAt indexPath:
cell.prescriptionButton.addTarget(self, action: Selector("onClicked:"), for: .touchUpInside)
funktion, die nach gedrückter Taste des Benutzers ausgeführt wird:
@objc func onClicked(sender: UIButton){
let tag = sender.tag
}