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 YourCellDelegate
protocol 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 YourCellDelegate
protocol.
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 cellForItemAt
for UICollectionView
or in cellForRowAt
for UITableView
将以下代码放入cellForItemAt
forUICollectionView
或 in cellForRowAt
forUITableView
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 tag
option. 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 inserted
or deleted
. Therefore, it is better to pass the cell
itself as a parameter rather than passing the button's tag
to 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
}
}
}