如何在 segue 中选择 table 查看单元格行?

How to get selected table view cell row in segue?

我正在使用 Swift 开发一个 iOS 应用程序,我有一个视图控制器,它通过 select 单元格行从 table 视图单元格内容视图中分离出来或者 select 在该单元格行的内容视图中点击一个按钮。包含 table 视图的原始视图控制器在两种不同的情况下执行转场:当单元格行本身被 selected 时转场(转至 avplayerviewcontroller 并根据单元格行播放视频是 selected) 并且当您按下位于 table 视图单元格的内容视图内的按钮时,会发生第二个 segue。在第一个 segue 中,当我覆盖第一个 segue 时,我能够传递 select 与 if let indexPath = self.tableview.indexPathForSelectedRow 编辑的单元格行。但是,当我尝试传递 selected 的单元格行时,当我尝试覆盖按下按钮时发生的第二个 segue 时,它​​不起作用。这是因为 table 视图单元格内的按钮不知道它被 select 编辑在哪一行?如果是这样,我该如何解决这个问题,如果不是,解决此类问题的可行解决方案是什么?提醒:当您 select 单元格行时会触发 "playDrill" 转场,当您 select 在同一单元格行的内容视图中按下按钮时会触发 "Tips" 转场

当您 select 一个单元格行时发生的第一个 segue 的代码(此 segue 根据需要运行):

class DrillsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "playDrill" {
        if let indexPath = self.tableView.indexPathForSelectedRow {
            if initialRow == 1 {
                drillVid = videoURL[indexPath.row]
                playerViewController = segue.destination as! PlayerController
                playerViewController.player = AVPlayer(playerItem: AVPlayerItem(url: drillVid))
                playerViewController.player?.play()
                print(indexPath) //prints correct value which is "[0,6]"
            }
            if initialRow == 3 {
                drillVid = videoUrl[indexPath.row]
                playerViewController = segue.destination as! PlayerController
                playerViewController.player = AVPlayer(playerItem: AVPlayerItem(url: drillVid))
                playerViewController.player?.play()
            }

当您 select 单元格内容视图中的按钮时触发的第二个转场代码(我希望此转场与第一个转场中一样具有 indexPath 的值,但是当我尝试使用它不 return 正确值的代码):

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "Tips" {
       if let indexPath = self.tableview.indexPathForSelectedRow {
        if initialRow == 1 {
            print(indexPath)  //the value printed is "6", I want "[0,6]" like the first code block
            let tipVC = segue.destination as! KeysController

            } 
        }
    }
}

我从未使用过 tableview.indexPathForSelectedRow(虽然我认为这不是好的做法,但我不确定它是否与您的问题有关),但是您可以尝试的另一种方法是发送 indexPath 对象为 sender。这将避免在 prepareForSegue 中检查 tableview.indexPathForSelectedRow。例如,

  • 您可以在 tableView(UITableView, didSelectRowAt: IndexPath) 中触发您的 "playDrill" segue,您可以在其中访问此 indexPath 并且可以简单地将其作为 sender.
  • 传递
  • 当触发你的 "Tips" segue 时,你也可以将这个 indexPath 对象作为发件人传递。获得引用的一种方法是在您使单元格出列并在 ableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath)
  • 中设置按钮操作时保留 indexPath 对象

如果对您有帮助,请告诉我!干杯,

朱利安

几个月前我也遇到过这个问题......最后我能够通过以下任务解决它:

  1. 在你对应的TableViewCell

  2. 中创建按钮的Outlet和Action
  3. 在您的 TableViewCell.swift 文件中创建一个 XYTableViewCellDelegate 协议

  4. 在您的 TableViewCell class

  5. 中定义您之前创建的 TableViewCell 委托的委托
  6. 在表视图的 cellForRowAt: 函数中定义委托

  7. 将委托添加到您的 ViewController class,其中还实现了 TableView

  8. 最后在你的 ViewController 中创建这个函数来接收点击的按钮 tableview indexpath

如果您需要更多帮助,请在此处复制/粘贴整个 ViewController 和 TableViewCell class - 我们可以直接在代码中进行更改。


它应该类似于下面的代码:

// FILE VIEWCONTORLLER
// -> 5.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, XYTableViewCellDelegate {

  // ... view did load stuff here

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
      let cell:TripDetailsTableViewCell = self.tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell

      // -> 4.
      cell.delegate = self

    // ... 
  }

  // -> 6.
  func buttonTappedViewCellResponse(cell: UITableViewCell) {
     let indexPath = tableView.indexPath(for: cell)
     // do further stuff here
  }
}


// FILE TABLEVIEWCELL
// -> 2.
protocol XYTableViewCellDelegate {
    func buttonTappedViewCellResponse(cell:UITableViewCell)
}
class XYTableViewCell: UITableViewCell {
  // -> 1.
  @IBOutlet weak var button: UIButton!

  // -> 3.
  var delegate: XYTableViewCellDelegate?

  // -> 1.
  @IBAction func buttonAction(_ sender: Any) {
    self.delegate?.buttonTappedViewCellResponse(cell: self)
  }
}

您无法获取选定单元格的选定索引,因为您实际上并未选择单元格。您正在按单元格内的按钮。

所以,您要做的是获取按钮的引用,获取按钮的超级视图(单元格),然后您可以获得该单元格的 indexPath

class TableViewController: UITableViewController {

    var indexPathForButton: IndexPath?

    @IBAction func buttonPressed(_ sender: UIButton) {

        let button = sender
        let cell = button.superview!.superview! as! MyCell  // The number of levels deep for superviews depends on whether the button is directly inside the cell or in a view in the cell
        indexPathForButton = tableView.indexPath(for: cell)
    }

然后在prepare(for segue:)

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.identifier == "Tips" {
        if initialRow == 1 {
          print(indexPathForButton)
          let tipVC = segue.destination as! KeysController
        }
    }
 }