ios 带有动作的 UITableViewCell 按钮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39947076/
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
UITableViewCell Buttons with action
提问by Hyman87
Hi I have a custom UITableViewCell with three buttons to handle a shopping cart function, Plus,Minus and Delete button and I need to know which cell has been touched.
嗨,我有一个自定义 UITableViewCell,它带有三个按钮来处理购物车功能、加号、减号和删除按钮,我需要知道触摸了哪个单元格。
I've already tried to use the "tag solution" but it isn't working due to the lifecycle of the cells.
我已经尝试使用“标签解决方案”,但由于细胞的生命周期,它不起作用。
Can anyone please help me find a solution?
任何人都可以帮我找到解决方案吗?
Thanks in advance
提前致谢
回答by pedrouan
I was resolving this using a cell delegate method within UITableViewCell's subclass.
我正在使用 UITableViewCell 的子类中的单元委托方法解决这个问题。
Quick overview:
快速概览:
1)Create a protocol
1)创建协议
protocol YourCellDelegate : class {
func didPressButton(_ tag: Int)
}
2)Subclassyour UITableViewCell(if you haven't done so):
2)子类化你的UITableViewCell(如果你还没有这样做):
class YourCell : UITableViewCell
{
var cellDelegate: YourCellDelegate?
@IBOutlet weak var btn: UIButton!
// connect the button from your cell with this method
@IBAction func buttonPressed(_ sender: UIButton) {
cellDelegate?.didPressButton(sender.tag)
}
...
}
3)Letyour view controllerconform to YourCellDelegateprotocol that was implemented above.
3)让你的视图控制器符合YourCellDelegate上面实现的协议。
class YourViewController: ..., YourCellDelegate { ... }
4)Set a delegate, after the cell has been defined (for reusing).
4)在定义单元格后设置一个委托(用于重用)。
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! YourCell
cell.cellDelegate = self
cell.btn.tag = indexPath.row
5)In the same controller (where is your implemented UITableView delegate/datasource), put a method from YourCellDelegateprotocol.
5)在同一个控制器中(你实现的 UITableView 委托/数据源在哪里),从YourCellDelegate协议中放置一个方法。
func didPressButton(_ tag: Int) {
print("I have pressed a button with a tag: \(tag)")
}
Now, your solution is not tag / number dependent. You can add as many buttons as you want, so you are ready to get response via delegate regardless how many buttons you want to install.
现在,您的解决方案不依赖于标签/数字。您可以根据需要添加任意数量的按钮,因此无论您要安装多少个按钮,您都可以通过委托获得响应。
This protocol-delegate solution is preferred in iOS logic and it can be used for other elements in table cell, like UISwitch, UIStepper, and so on.
这种协议委托解决方案在 iOS 逻辑中是首选,它可以用于表格单元格中的其他元素,如UISwitch、UIStepper等。
回答by Frederico
I came across the same problem after making the IBOutlets private as has been broadly suggested by the community.
在按照社区的广泛建议将 IBOutlets 设为私有后,我遇到了同样的问题。
Here is my solution:
这是我的解决方案:
< In your cell class >
<在你的单元格类中>
protocol YourCellDelegate: class {
func didTapButton(_ sender: UIButton)
}
class YourCell: UITableViewCell {
weak var delegate: YourCellDelegate?
@IBAction func buttonTapped(_ sender: UIButton) {
delegate?.didTapButton(sender)
}
}
< In your ViewController >
< 在你的 ViewController >
class ViewController: UIViewController, YourCellDelegate {
func didTapButton(_ sender: UIButton) {
if let indexPath = getCurrentCellIndexPath(sender) {
item = items[indexPath.row]
}
}
func getCurrentCellIndexPath(_ sender: UIButton) -> IndexPath? {
let buttonPosition = sender.convert(CGPoint.zero, to: tableView)
if let indexPath: IndexPath = tableView.indexPathForRow(at: buttonPosition) {
return indexPath
}
return nil
}
}
回答by RimK
swift 4.2
快速 4.2
You can also use closures instead of delegates
您还可以使用闭包代替委托
1) In your UITableViewCell :
1) 在你的 UITableViewCell 中:
class ExampleCell: UITableViewCell {
//create your closure here
var buttonPressed : (() -> ()) = {}
@IBAction func buttonAction(_ sender: UIButton) {
//Call your closure here
buttonPressed()
}
}
2) In your ViewController
2) 在你的 ViewController 中
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ExampleCell", for: indexPath) as! ExampleCell
cell.buttonPressed = {
//Code
}
return cell
}
}
回答by Abhishek Mitra
SWIFT 4.*
斯威夫特 4.*
It can be done like following way too, Not required much coding and delegation, Simple and easy.
它也可以像下面这样完成,不需要太多的编码和委托,简单易行。
Put following code in cellForItemAtfor UICollectionViewor in cellForRowAtfor UITableView
将以下代码放入cellForItemAtforUICollectionView或 in cellForRowAtforUITableView
cell.btn.tag = indexPath.row
cell.btn.addTarget(self, action: #selector(buttonSelected), for: .touchUpInside)
And your Method will be
你的方法将是
@objc func buttonSelected(sender: UIButton){
print(sender.tag)
}
Thats all.
就这样。
回答by Changnam Hong
@pedrouan is great, except using button's tagoption. In many cases, when you set button on tableViewCell, those buttons will modify tableView dataSource.(e.g. InsertRow, DeleteRow).
@pedrouan 很棒,除了使用按钮的tag选项。在许多情况下,当您设置按钮时tableViewCell,这些按钮将修改 tableView 数据源。(例如 InsertRow、DeleteRow)。
But the tag of the button is not updated even if a new cell is insertedor deleted. Therefore, it is better to pass the cellitself as a parameter rather than passing the button's tagto the parameter.
但是即使新单元格是inserted或,按钮的标签也不会更新deleted。因此,最好将其cell本身作为参数传递,而不是将按钮的传递tag给参数。
Here is my example to achieve this.
这是我实现这一目标的示例。
Your ExampleCell
您的 ExampleCell
protocol ExampleCellDelegate: class {
func didTapButton(cell: ExampleCell)
}
class ExampleCell: UITableViewCell {
weak var cellDelegate: ExampleCellDelegate?
@IBAction func btnTapped(_ sender: UIButton) {
cellDelegate?.didTapButton(cell: self)
}
}
Your ViewController
您的 ViewController
class ViewController: ExampleCellDelegate {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "ExampleCell", for: indexPath) as? ExampleCell {
cell.cellDelegate = self
return cell
}
return UITableViewCell()
}
func didTapButton(cell: ExampleCell) {
if let indexPath = tableView.indexPath(for: cell) {
// do Something
}
}
}
回答by KKRocks
You can also get selected button index using tableViewCell view's hierarchy.
您还可以使用 tableViewCell 视图的层次结构获取选定的按钮索引。
Using following steps :
使用以下步骤:
add selector to the cellForRowAtIndexpath of tableview :
btn?.addTarget(self, action:#selector(buttonPressed(_:)), for:.touchUpInside)
将选择器添加到 tableview 的 cellForRowAtIndexpath :
btn?.addTarget(self, action:#selector(buttonPressed(_:)), for:.touchUpInside)
2 . get indexPath using following method :
2 . 使用以下方法获取 indexPath :
func buttonPressed(_ sender: AnyObject) {
let button = sender as? UIButton
let cell = button?.superview?.superview as? UITableViewCell
let indexPath = tblview.indexPath(for: cell!)
print(indexPath?.row)
}
回答by Himanshu Moradiya
UIButton in Tableview cell. Programically create action method in swift 4.2
Tableview 单元格中的 UIButton。在 swift 4.2 中以编程方式创建操作方法
cell.btnlike.addTarget(self, action: #selector(buttonbtnlikePressed(_:event:)), for: .touchUpInside)
@objc func buttonbtnlikePressed(_ sender: Any, event: Any) {
let point : CGPoint = (sender as AnyObject).convert(CGPoint.zero, to:tblPost)
var indexPath = self.tblPost!.indexPathForRow(at: point)
if let btnlike = sender as? UIButton{
if btnlike.isSelected{
btnlike.isSelected = false
}else{
btnlike.isSelected = true
}
}
}

