ios 表格视图单元格中的 UIButton 操作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28894765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 05:07:49  来源:igfitidea点击:

UIButton action in table view cell

iosswiftuitableviewparsing

提问by Sammmmm

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.

在我的 UITableViewCell 类中名为 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.

我正在使用 Parse 来保存数据,并希望在按下按钮时更新一个对象。我的 objectIds 数组工作正常,cell.yes.tag 也将正确的数字打印到日志中,但是,我无法将该数字输入到我的“连接”函数中,以便正确运行我的查询。

I need a way to get the indexPath.row of the cell to find the proper objectId.

我需要一种方法来获取单元格的 indexPath.row 以找到正确的 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()
        }
    }

}

回答by IxPaka

Swift 4 & Swift 5:

斯威夫特 4 和斯威夫特 5:

You need to add target for that button.

您需要为该按钮添加目标。

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

And of course you need to set tag of that button since you are using it.

当然,您需要设置该按钮的标签,因为您正在使用它。

myButton.tag = indexPath.row

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.

您可以通过继承 UITableViewCell 来实现这一点。在界面生成器中使用它,在该单元格上放一个按钮,通过插座连接它,然后就可以了。

To get the tag in the connected function:

要在连接的函数中获取标签:

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

回答by Benedikt Reichert

The accepted answer using button.tagas information carrier which button has actually been pressed is solid and widely accepted but rather limited since a tag can only hold Ints.

使用button.tag实际按下按钮作为信息载体的公认答案是可靠且广泛接受的,但相当有限,因为标签只能容纳Ints。

You can make use of Swift's awesome closure-capabilities to have greater flexibility and cleaner code.

您可以利用 Swift 令人敬畏的闭包功能来获得更大的灵活性和更清晰的代码。

I recommend this article: How to properly do buttons in table view cells using Swift closuresby Jure Zove.

我推荐这篇文章:如何使用Jure Zove 的Swift 闭包在表格视图单元格中正确执行按钮

Applied to your problem:

应用于您的问题:

  1. Declare a variable that can hold a closure in your tableview celllike

    var buttonTappedAction : ((UITableViewCell) -> Void)?
    
  2. 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 @IBActionoutlet :-)

    @IBAction func buttonTap(sender: AnyObject) {
       tapAction?(self)
    }
    
  3. Now pass the content of func connected(sender: UIButton!) { ... }as a closure to cell.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.
  1. 声明一个可以在 tableview单元格中保存闭包的变量,例如

    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...>}。请参阅文章以获得更精确的解释,并且在从环境中捕获变量时请不要忘记打破引用循环。

回答by kalpesh

Simple and easy way to detect button event and perform some action

检测按钮事件并执行某些操作的简单方法

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

}

回答by levin varghese

We can create a closure for the button and use that in cellForRowAtIndexPath

我们可以为按钮创建一个闭包并在 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)
 }
}

And then in cellForRowAtIndexPath

然后在 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
 }

回答by Biswajit Banik

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

回答by swiftBoy

With Swift 5this is what, worked for me!!

使用Swift 5,这对我有用!!

Step 1. Created IBOutlet for UIButton in My CustomCell.swift

步骤 1. 在 My CustomCell.swift 中为 UIButton 创建 IBOutlet

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

Step 2. Added action method in CellForRowAtIndex method and provided method implementation in the same view controller

步骤 2. 在 CellForRowAtIndex 方法中添加 action 方法并在同一视图控制器中提供方法实现

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

回答by Huy Nghia

As Apple DOC

作为苹果文档

targetForAction:withSender:
Returns the target object that responds to an action.

targetForAction:withSender:
返回响应动作的目标对象。

You can't use that method to set target for UIButton.
Try addTarget(_:action:forControlEvents:)method

您不能使用该方法为UIButton.
尝试 addTarget(_:action:forControlEvents:)方法

回答by Ammar Mujeeb

The accepted answer is good and simple approach but have limitation of information it can hold with tag. As sometime more information needed.

接受的答案是好的和简单的方法,但它可以用标签保存的信息有限。有时需要更多信息。

You can create a custom button and add properties as many as you like they will hold info you wanna pass:

您可以创建一个自定义按钮并添加任意数量的属性,它们将包含您想要传递的信息:

class CustomButton: UIButton {
    var orderNo = -1
    var clientCreatedDate = Date(timeIntervalSince1970: 1)
}

Make button of this type in Storyboard or programmatically:

在 Storyboard 中或以编程方式制作这种类型的按钮:

protocol OrderStatusDelegate: class {
    func orderStatusUpdated(orderNo: Int, createdDate: Date)
}

class OrdersCell: UITableViewCell {
    @IBOutlet weak var btnBottom: CustomButton!
    weak var delegate: OrderStatusDelegate?
}

While configuring the cell add values to these properties:

在配置单元格时,向这些属性添加值:

 func configureCell(order: OrderRealm, index: Int) {
     btnBottom.orderNo = Int(order.orderNo)
     btnBottom.clientCreatedDate = order.clientCreatedDate
 }

When tapped access those properties in button's action (within cell's subclass) that can be sent through delegate:

当点击访问可以通过委托发送的按钮操作(在单元格的子类中)中的那些属性时:

@IBAction func btnBumpTapped(_ sender: Any) {
    if let button = sender as? CustomButton {
        let orderNo = button.orderNo
        let createdDate = button.clientCreatedDate
        delegate?.orderStatusUpdated(orderNo: orderNo, createdDate: createdDate)
    }
}

回答by m azizi

in Swift 4

在斯威夫特 4

in cellForRowAt indexPath:

在 cellForRowAt 索引路径中:

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

function that run after user pressed button:

用户按下按钮后运行的功能:

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


    }