【问题标题】:Swift 3.0 TableView Cell ButtonSwift 3.0 TableView 单元格按钮
【发布时间】: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 堆叠。
  • 您的表格视图有一些数据模型(通常是数组)在驱动它;您将跟踪此模型中的当前状态并采取相应措施

标签: ios swift uitableview


【解决方案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 
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 1970-01-01
      • 1970-01-01
      • 2016-08-05
      相关资源
      最近更新 更多