Swift 3.0 TableView 单元格按钮
Posted
技术标签:
【中文标题】Swift 3.0 TableView 单元格按钮【英文标题】:Swift 3.0 TableView Cell Button 【发布时间】:2017-08-03 02:45:22 【问题描述】:我在 tableview 单元格上设置了一个按钮,我想知道如何操作它。即,我有兴趣更改按钮的名称标题并在单击按钮时添加另一个目标(按钮的不同功能)。我的想法是这需要添加到 buttonClicked 函数中,但我不确定如何引用被点击的特定 cellForRow。也许可以在 cellForRow 中使用一个条件来确定按钮标题是什么?我不太确定最好的方法是什么。
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = guestTableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let button : UIButton = UIButton(type:UIButtonType.custom) as UIButton
button.frame = CGRect(origin: CGPoint(x: 200,y :60), size: CGSize(width: 100, height: 24))
let cellHeight: CGFloat = 44.0
button.center = CGPoint(x: view.bounds.width / (4/3), y: cellHeight / 2.0)
button.setTitleColor(.blue, for: .normal)
button.addTarget(self, action: #selector(buttonClicked), for: UIControlEvents.touchUpInside)
button.setTitle("Add", for: UIControlState.normal)
cell.addSubview(button)
return cell
func buttonClicked(sender : UIButton!)
print("Added!")
【问题讨论】:
每次单元格出列时,此代码都会在单元格中堆叠 UIButtons。 (由于出队检索到不再使用但不一定是新的,所以它已经存在) @Pochi 我不太确定出队是什么意思以及它在表格视图中扮演什么角色,以及当单元格出队时,你能解释一下吗?如何避免重复使用这些单元格? 你不避免重复使用单元格,那是 UITableView 的优化。您要做的是通过界面构建器创建自己的 UITableViewCell 子类,然后您可以将按钮连接到那里的属性。当您使用上面的代码时,只需使用“as!”将其转换为您的自定义子类。并直接访问按钮。由于您现在有一个自定义子类,您还可以添加一个属性来识别单元格。上面的代码也要设置这个属性,(保存当前索引就可以了),那么你就可以很容易地知道哪个单元格被按下了。 是的,它会避免 UIButton 堆叠。 您的表格视图有一些数据模型(通常是数组)在驱动它;您将跟踪此模型中的当前状态并采取相应措施 【参考方案1】:适用于 Swift 4 和 Swift 5
查找“indexPath.row
”和“indexPath.section
”
//在“cellForRowAt”中的按钮上添加目标
cell.myBtn.addTarget(self, action: #selector(self.btnAction(_:)), for: .touchUpInside)
// 添加函数
func btnAction(_ sender: UIButton)
let point = sender.convert(CGPoint.zero, to: yourTableView as UIView)
let indexPath: IndexPath! = yourTableView.indexPathForRow(at: point)
print("row is = \(indexPath.row) && section is = \(indexPath.section)")
【讨论】:
【参考方案2】:使用您的代码更改和添加
button.addTarget(self, action:#selector(YourViewController.buttonClicked(_:)), for: .touchUpInside)
button.tag = indexPath.row
func buttonClicked(sender : UIButton!)
print("Added!")
let row = sender.tag;
print(row)
【讨论】:
这正是我所做的!标签与按钮所在的行相同,您可以将其设置为函数内部的变量或将其设置为类范围的变量,以便您可以在其他函数中访问该行。 我不太明白如何使用标签。每个标签是否与不同的按钮质量(功能、标题等)相关联。如何将这些品质与标签关联起来? button.tag 是存储 indexpath.row 的值,因此每当您单击按钮时,都会将标签值作为 indexpath.row 获取,之后您就可以做自己的事情了 在按钮上点击你想要的,如果有任何疑问我会帮助你? 默认情况下,我希望按钮说“添加”,但是一旦单击它,我希望它说“减”和另一个返回以添加,并在单击“减”时调用一个函数。 【参考方案3】:有两种方法可以做到 - 作弊的方式或正确的方式。正确的做法是继承 UITableViewCell,在这种情况下,您可以以正常方式连接插座。作弊的方法是使用每个元素的标签属性。如果将按钮的标签设置为(比如说)1,则可以在cellForRowAt
中使用cell.viewWithTag
来定位它:如:
let button = cell.viewWithTag(1) as! UIButton
请注意,它将搜索cell
下面的整个层次结构,因此您需要确保您没有多个具有相同标签的子视图。
根据您的问题,我猜您想单击按钮并更改其标题。点击处理程序应该只重新加载 tableView 行(或整个表,如果你像我一样懒惰),cellForRowAt
需要知道要显示什么标题。这种在每行按钮上显示的状态必须保持在 tableView 单元格之外,因为在滚动时会重复使用单元格。这意味着一旦第一行滚动离开屏幕,相同的单元格可能会被重新用于(比如说)第 20 行。 cellForRowAt
中的代码需要完全重置单元格的内容,以防它已经用于另一行。
从您对问题的评论中添加一些细节,您永远不想避免重复使用单元格,因为这是一件非常好的事情。您可能会显示一个包含 1,000 行的表格,但屏幕上只有 10 行可见。重用单元格意味着 ios 可以创建少至 10 个单元格来显示整个表格,而不是 1,000 个。因此性能更快。
【讨论】:
啊,我明白了出队的作用,感谢您的澄清。您提到的这两种方式除了如何实现之外,还有什么区别?tag
的使用有点小技巧,容易出现问题。例如,如果您复制/粘贴按钮,新按钮将获得相同的标签(除非您记得更改它)并且您的代码可能无法按预期工作。子类化UITableViewCell
允许您将特定于视图的行为放在视图中,这是“正确”的做法。话虽如此,我 80% 的时间都使用作弊方式,因为它更容易。其他 20% 往往是我有多个单元原型的情况,具体取决于行类型,这使得 cellForRowAt
中的它更加清晰。【参考方案4】:
在 Swift 4.x 中,您可以简单地让 TableView 的委托为其设置一个标签,如下所示:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
// Assign tags
cell.myButton.tag = indexPath.row
return cell
然后通过右键单击并拖动到您的.swift
文件作为@IBAction
连接故事板中的按钮,选择Type -> UIButton 并单击连接。
代码如下:
@IBAction func myButt(_ sender: UIButton)
let buttTag = sender.tag // get the Tag of the clicked button in the Cell
// write the code that will be called on click of your button
【讨论】:
以上是关于Swift 3.0 TableView 单元格按钮的主要内容,如果未能解决你的问题,请参考以下文章
swift 3 在tableView 中按下了哪个单元格按钮