web-dev-qa-db-ja.com

テーブルビューセルのUIButtonアクション

テーブルビューセル内で押されているボタンのアクションを実行しようとしています。次のコードは、Table View Controllerクラスにあります。

ボタンは、requestsCellと呼ばれるUITableViewCellのクラスのアウトレットで「はい」と説明されています。

Parseを使用してデータを保存していますが、ボタンが押されたときにオブジェクトを更新したいと思います。 objectIds配列は正常に機能し、cell.yes.tagは正しい番号をログに出力しますが、クエリを適切に実行するために「接続された」関数にその番号を取得することはできません。

適切なobjectIdを見つけるために、セルのindexPath.rowを取得する方法が必要です。

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

}
40
Sammmmm

Swift 4&Swift 5:

そのボタンのターゲットを追加する必要があります。

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

そしてもちろん、ボタンを使用しているため、そのボタンのタグを設定する必要があります。

myButton.tag = indexPath.row

これを実現するには、UITableViewCellをサブクラス化します。インターフェースビルダーで使用し、そのセルにボタンをドロップし、アウトレット経由で接続すると、そこに行きます。

接続された関数でタグを取得するには:

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

ボタンが実際に押された情報キャリアとしてbutton.tagを使用した受け入れられた回答は堅実で広く受け入れられていますが、タグはIntsのみを保持できるため、かなり制限されています。

Swiftの優れたクロージャー機能を利用して、柔軟性とコードをよりクリーンにすることができます。

この記事をお勧めします: Swiftクロージャーを使用してテーブルビューセルでボタンを適切に行う方法 by Jure Zove。

あなたの問題に適用:

  1. テーブルビューでクロージャを保持できる変数を宣言しますcell

    var buttonTappedAction : ((UITableViewCell) -> Void)?
    
  2. ボタンが押されたときにクロージャーのみを実行するアクションを追加します。 cell.yes.targetForAction("connected", withSender: self)を使用してプログラムで実行しましたが、@IBActionアウトレットを使用したいと思います:-)

    @IBAction func buttonTap(sender: AnyObject) {
       tapAction?(self)
    }
    
  3. func connected(sender: UIButton!) { ... }のコンテンツをクロージャーとしてcell.tapAction = {<closure content here...>}に渡します。より正確な説明については記事を参照してください。また、環境から変数をキャプチャするときに参照サイクルを中断することを忘れないでください。
39

ボタンイベントを検出して何らかのアクションを実行するシンプルで簡単な方法

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

}
31
kalpesh

ボタンのクロージャーを作成し、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)
 }
}

そして、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
 }
3
levin varghese
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")
   }
}
2
Biswajit Banik

As Apple DOC

targetForAction:withSender:
アクションに応答するターゲットオブジェクトを返します。

そのメソッドを使用してUIButtonのターゲットを設定することはできません。
Try addTarget(_:action:forControlEvents:) method

1
Huy Nghia

Swift 5で、これは私にとってはうまくいきました!!

手順1. My CustomCell.SwiftにUIButton用のIBOutletを作成しました

class ListProductCell: UITableViewCell {
@IBOutlet weak var productMapButton: UIButton!
//todo
}

手順2. CellForRowAtIndexメソッドにアクションメソッドを追加し、同じView Controllerにメソッド実装を提供

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

Swift 4

cellForRowAt indexPathで:

 cell.prescriptionButton.addTarget(self, action: Selector("onClicked:"), for: .touchUpInside)

ユーザーがボタンを押した後に実行される関数:

@objc func onClicked(sender: UIButton){
        let tag = sender.tag


    }
0
m azizi