0

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

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

            } 
        }
    }
}
4

3 回答 3

1

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

  1. 在相应的按钮中创建一个 Outlet 和 ActionTableViewCell

  2. 在文件中创建XYTableViewCellDelegate协议TableViewCell.swift

  3. TableViewCell在您的TableViewCell班级 中定义您之前创建的委托的委托

  4. cellForRowAt:在表格视图的功能中定义您的委托

  5. 将委托添加到您的 ViewController 类,其中也实现了 TableView

  6. 最后只需在您的 ViewController 中创建此函数即可接收点击的按钮 tableview indexpath

如果您需要更多帮助,请在此处复制/粘贴整个 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)
  }
}
于 2017-09-19T21:45:40.547 回答
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
        }
    }
 }
于 2017-09-19T22:16:55.760 回答
0

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

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

让我知道这是否对您有帮助!干杯,

朱利安

于 2017-09-19T21:33:50.410 回答