如何在segue中获取选定的表格视图单元格行?

时间:2017-09-19 21:04:39

标签: ios swift override segue indexpath

我正在使用Swift开发一个iOS应用程序,我有一个视图控制器,它通过选择一个单元格行或在该单元格行的内容视图中选择一个按钮,从表视图单元格内容视图中分离出来。包含表视图的原始视图控制器在两个不同的场合执行segue:当选择单元行本身时一个segue(根据选择的单元格行调整为avplayerviewcontroller并播放视频),第二个segue发生时您按下表视图单元格的内容视图内的按钮。在第一个segue中,当我覆盖第一个segue时,我能够传递用if let indexPath = self.tableview.indexPathForSelectedRow选择的单元格行。但是,当我尝试传递当我尝试覆盖按下按钮时发生的第二个segue时所选择的单元格行,它不起作用。这是因为表格视图单元格内的按钮不知道选择了哪一行?如果是这样,我该如何解决这个问题,如果没有解决这个问题的可行解决方案呢?提醒:当您选择单元格行时会触发“playDrill”segue,当您在同一单元格行的内容视图中选择一个按钮时会触发“Tips”segue

选择单元格行时发生的第一个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()
            }

当你在单元格的内容视图中选择一个按钮时触发的第二个segue的代码(我希望这个segue的值为indexPath,就像在第一个segue中一样,但当我尝试使用该代码时没有返回正确的值):

 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

            } 
        }
    }
}

3 个答案:

答案 0 :(得分:1)

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

  1. 在相应的TableViewCell

  2. 中创建按钮的插座和操作
  3. XYTableViewCellDelegate文件中创建TableViewCell.swift协议

  4. TableViewCell班级

  5. 中定义您之前创建的TableViewCell代表的代理人
  6. 在tableview的cellForRowAt:函数中定义代理

  7. 将委托添加到同样实现TableView的ViewController类中

  8. 最后在ViewController中创建此函数以接收tapped按钮tableview indexpath

  9. 如果您需要更多帮助,请复制/粘贴整个ViewController& TableViewCell类在这里 - 我们可以直接在代码中进行更改。

    它应该类似于以下代码:

    // 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)
      }
    }
    

答案 1 :(得分:0)

我从未使用tableview.indexPathForSelectedRow(虽然我认为这不是一个好习惯,但我不确定它是否对您的问题负责),但是您可能尝试的另一种方法是发送{{1对象为indexPath。这样可以避免在sender内检查tableview.indexPathForSelectedRow。例如,

  • 您可以在prepareForSegue "playDrill"中触发tableView(UITableView, didSelectRowAt: IndexPath) segue,只有indexPath才能访问sender
  • 触发"Tips" segue时,您也可以将此indexPath对象作为发件人传递。获取引用的一种方法是在单元格出列时保留indexPath对象,并在ableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath)
  • 中设置按钮操作

如果有帮助,请告诉我!欢呼声,

于连

答案 2 :(得分:0)

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

所以,你要做的是获得对按钮的引用,获取按钮的超级视图(单元格),然后你就可以获得该单元格的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
        }
    }
 }