在tableview中检测uibutton:Swift Best Practices

jam*_*ike 40 uibutton uitableview ios swift

我有一个tableview,其中包含可变数量的单元格,表示与其特定教师相对应的学生.它们是具有按钮的自定义单元格,该按钮触发新VC的segue,提供有关其单元格的学生的详细信息.我的问题是:

swift中用于识别按下哪个按钮的最佳做法是什么?

一旦我知道索引路径,我就可以确定哪个学生的信息需要传递给下一个VC.在下面的帖子中,对于目标C有一个很好的答案,但我不确定如何转换为Swift.任何帮助将非常感激.

检测在UITableView中按下了哪个UIButton

Lyn*_*ott 84

如果您的代码允许,我建议您将UIButton标记设置为等于indexPath.row,因此当触发其操作时,您可以拉动标记,从而在触发方法期间排出按钮数据.例如,cellForRowAtIndexPath您可以设置标签:

button.tag = indexPath.row
button.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
Run Code Online (Sandbox Code Playgroud)

然后buttonClicked:,你可以获取标签,从而获取行:

func buttonClicked(sender:UIButton) {

    let buttonRow = sender.tag
}
Run Code Online (Sandbox Code Playgroud)

否则,如果由于某种原因这不利于你的代码,你链接到这个Objective-C答案的Swift翻译:

- (void)checkButtonTapped:(id)sender
{
    CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
    if (indexPath != nil)
    {
     ...
    }
}
Run Code Online (Sandbox Code Playgroud)

是:

func checkButtonTapped(sender:AnyObject) {
      let buttonPosition = sender.convert(CGPoint.zero, to: self.tableView)
    let indexPath = self.tableView.indexPathForRow(at: buttonPosition)
    if indexPath != nil {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不要使用标记方法.插入,删除或移动行时会出现许多问题.始终使用第二种解决方案. (3认同)

Sou*_*rma 15

Swift 3.0解决方案

cell.btnRequest.tag = indexPath.row

    cell.btnRequest.addTarget(self,action:#selector(buttonClicked(sender:)), for: .touchUpInside)

    func buttonClicked(sender:UIButton) {

            let buttonRow = sender.tag
        }
Run Code Online (Sandbox Code Playgroud)

  • 这个对我有用!! 由于我认为选择器是如何设置的,其他人都没有工作.谢谢! (3认同)
  • 不要使用这种方法。在许多情况下,使用标签来跟踪行会失败。 (2认同)

dar*_*nge 6

针对Swift 3进行了更新

如果您想要做的唯一事情是触摸触发segue,那么通过UIButton这样做是违反最佳做法的.您可以简单地使用UIKit的内置处理程序来选择单元格,即func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath).您可以执行以下操作:

创建自定义UITableViewCell

class StudentCell: UITableViewCell {
    // Declare properties you need for a student in a custom cell.
    var student: SuperSpecialStudentObject!

    // Other code here...
}
Run Code Online (Sandbox Code Playgroud)

加载UITableView时,将数据从您的数据模型传递到单元格中:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "StudentCell", for: indexPath) as! StudentCell
    cell.student = superSpecialDataSource[indexPath.row]
    return cell
}
Run Code Online (Sandbox Code Playgroud)

然后用于didSelectRow atIndexPath检测何时选择了一个单元格,访问单元格及其数据,并将值作为参数传递给performSegue.

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath) as! StudentCell

    if let dataToSend = cell.student {
        performSegue(withIdentifier: "DestinationView", sender: dataToSend)
    }
}
Run Code Online (Sandbox Code Playgroud)

最后在prepareForSegue:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "DestinationView" {
        let destination = segue.destination as! DestinationViewController
        if let dataToSend = sender as? SuperSpecialStudentObject {
            destination.student = dataToSend
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您希望它们仅选择单元格的一部分而不是它们触摸单元格内的任何位置,您可以将附件项目添加到单元格中,例如细节附件项目(看起来像内部带有"i"的圆圈)它)并override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath)改为使用.