2017-08-03 115 views
1

我已经在tableview单元格上设置了一个按钮,我想知道如何操纵它。也就是说,我有兴趣改变按钮的名称标题,并在点击按钮时添加另一个目标(按钮的不同功能)。我的想法是,这需要被添加到buttonClicked func中,但我不确定如何引用被单击的特定cellForRow。也许可以在cellForRow中使用一个条件来确定按钮标题是什么?我不太确定最好的方法是什么。Swift 3.0 TableView单元格按钮

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


} 
+1

此代码会在您的单元中每次出现单元时都堆叠UIButtons。 (因为出列检索不再使用,但不一定是新的,所以不管它已经存在) – Pochi

+0

@Pochi我不太清楚什么是出队的意思,它在桌面浏览中起什么作用,以及何时出现单元格出院了,你能解释一下吗?我怎样才能避免这些细胞的重用? – Kevin

+2

你不避免重用单元,这是一个UITableView优化。你需要做的是通过界面生成器创建你自己的UITableViewCell的子类,然后你可以将你的按钮连接到一个属性。当你使用上面的代码时,只需使用“as!”将它转换为你的自定义子类。并直接访问该按钮。既然你现在有一个自定义的子类,你也可以添加一个属性来标识单元格。这个属性也必须在上面的代码中设置(简单地保存当前索引是好的),那么你将能够很容易地知道哪个单元格被按下。 – Pochi

回答

2

有两种方法可以做到这一点 - 欺骗的方式或正确的方式。正确的是子类UITableViewCell,在这种情况下,你可以以正常的方式连接插座。作弊的方式是使用每个元素的标签属性。如果按钮的标签设置为(比方说)1,您可以使用内cellForRowAtcell.viewWithTag找到它:如:

let button = cell.viewWithTag(1) as! UIButton 

要知道,它会搜索以下cell整个层次,所以你需要确保您没有多个具有相同标签的子视图。

从你的问题,我猜你想点击按钮,并改变其标题。点击处理程序应该重新加载tableView行(或者如果你像我一样懒的话,整个表),并且cellForRowAt需要知道显示的标题。在每个行的按钮上显示的状态必须保存在tableView单元格之外,因为滚动时单元格会被重用。这意味着一旦顶行从屏幕上滚动出来,那么相同的单元格可能会重用于(比如说)第20行。 cellForRowAt中的代码需要完全重置单元格的内容,以防其已用于另一行。

在您对该问题的评论中添加一些细节,您永远不想避免重复使用单元格,因为这是一件非常好的事情。您可能会显示1,000行的表格,但屏幕上只能显示10行。重复使用单元格意味着iOS可以创建少至10个单元格来显示整个表格,而不是1,000个。因此性能更快。

+0

啊,我明白什么是出队,谢谢你的澄清。除了如何实现它们之外,你提到的两种方式之间有什么区别? – Kevin

+0

“标签”的使用有点破绽,容易出现问题。例如,如果您复制/粘贴您的按钮,新的按钮将会得到相同的标签(除非您记得更改它),并且您的代码可能无法按预期工作。 UITableViewCell的子类允许你在视图内部放置特定于视图的行为,这是“正确”的方式。话虽如此,80%的时间我都会使用秘籍方式,因为它更容易。另外的20%往往是我根据行类型拥有多个单元格原型的情况,它使'cellForRowAt'变得更清晰。 – Michael

3

Chnage并添加您的代码

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) 

} 
+0

这正是我所做的!标签等于按钮所在的行,您可以将其设置为函数内部的变量,或者将其设置为全班级变量,以便您可以访问其他函数中的行。 –

+0

我不太了解我如何使用标签。每个标签都与不同的按钮质量(功能,标题等)相关联。我如何将这些特质与标签联系起来? – Kevin

+0

button.tag是存储indexpath.row的值,所以每当你点击按钮然后获得标签值作为indexpath.row所以之后,你可以做你的东西 –

4

对于雨燕3.2和4.0

查找 “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)") 
} 
相关问题