表视图单元格中的UIButton操作

时间:2015-03-06 08:24:00

标签: ios swift uitableview parsing

我正在尝试为在表格视图单元格中按下的按钮运行操作。以下代码在我的表视图控制器类中。

在我的UITableViewCell类中名为requestsCell的插座中,该按钮被描述为“是”。

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

我需要一种方法来获取单元格的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()
        }
    }

}

10 个答案:

答案 0 :(得分:87)

Swift 4&斯威夫特5:

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

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

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

myButton.tag = indexPath.row

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

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

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

答案 1 :(得分:35)

使用button.tag作为实际按下按钮的信息载体的已接受答案是可靠且广泛接受的,但相当有限,因为标记只能保留Int s。

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

我推荐这篇文章:Jure Zove的How to properly do buttons in table view cells using Swift closures

适用于您的问题:

  1. 声明一个可以在tableview 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...>}。请参阅文章以获得更准确的解释,请不要忘记在从环境中捕获变量时中断参考周期。

答案 2 :(得分:28)

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

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

}

答案 3 :(得分:3)

我们可以为按钮创建一个闭合,并在cellForRowAtIndexPath中使用它

# >>> my_input()
# Important ions are: Na K Ca Mg Mn
# Important ions are: Na, Na, K, Ca, Mg and Mn

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

答案 4 :(得分:2)

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

答案 5 :(得分:1)

作为Apple DOC

  

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

您无法使用该方法为UIButton设置目标 尝试 addTarget(_:action:forControlEvents:)方法

答案 6 :(得分:0)

在Swift 4中

在cellForRowAt indexPath中:

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

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

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


    }

答案 7 :(得分:0)

借助 Swift 5 ,这对我有用!

步骤1。在我的CustomCell.swift中为UIButton创建IBOutlet

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

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

答案 8 :(得分:0)

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

您可以创建一个自定义按钮并添加尽可能多的属性,这些属性将保存您想要传递的信息:

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

在情节提要中或通过编程方式使这种类型的按钮:

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

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

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

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

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

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

答案 9 :(得分:0)

让我提供另一种从单元格中的按钮获取单元格的方法。

这个想法是对 UIButton 进行子类化,只是为了打开一个指向 weakUITableViewCell 指针。

class MyButton: UIButton {
    @objc weak var cell: UITableViewCell?
}

UITableViewCell 中:

override func awakeFromNib() {
    super.awakeFromNib()
    
    myButton.cell = self
}

在表格视图的 ViewController 中,按钮连接的地方:

@IBAction func myButtonAction(sender: MyButton) {
    let parentCell = sender.cell
    ...
}