Как получить выбранную строку ячейки представления таблицы в segue?

Я разрабатываю приложение для iOS с использованием Swift, и у меня есть контроллер представления, который сегментируется из представления содержимого ячейки табличного представления путем выбора строки ячейки или нажатия кнопки внутри представления содержимого этой строки ячейки. Исходный контроллер представления, который содержит табличное представление, выполняет переход в двух разных случаях: один переход, когда выбирается сама строка ячейки (переключается на контроллер avplayerview и воспроизводит видео в зависимости от выбранной строки ячейки), а второй переход происходит, когда Вы нажимаете кнопку, которая находится внутри представления содержимого ячейки представления таблицы. В первом сеансе я могу передать строку ячеек, выбранную с помощью if let indexPath = self.tableview.indexPathForSelectedRow когда я переопределяю первый переход. Однако, когда я пытаюсь пропустить строку ячеек, которая была выбрана, когда я пытаюсь переопределить второй переход, который происходит, когда вы нажимаете кнопку, он не работает. Это потому, что кнопка внутри ячейки табличного представления не знает, в какой строке она была выбрана? Если да, то как я могу решить эту проблему, и если нет, то как можно решить эту проблему? Напоминание: переход "playDrill" запускается при выборе строки ячейки, переход "Советы" запускается при нажатии кнопки внутри представления содержимого той же строки ячейки

Код для первого перехода, который происходит при выборе строки ячейки (этот переход работает по желанию):

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

Код для второго перехода, который срабатывает при выборе кнопки внутри представления содержимого ячейки (я хочу, чтобы этот переход имел значение indexPath как в первом переходе, но когда я пытаюсь использовать этот код, он не возвращает правильное значение):

 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 ответа

Решение

Вы не можете получить выбранный индекс выбранной ячейки, потому что вы на самом деле не выбираете ячейку. Вы нажимаете кнопку внутри клетки.

Итак, что вы делаете, это получаете ссылку на кнопку, получаете суперпредставление кнопки (ячейка), а затем вы можете получить 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
        }
    }
 }

У меня была эта проблема также пару месяцев назад... наконец я смог решить ее с помощью следующих задач:

  1. Создайте розетку и действие кнопки в своем соответствующем TableViewCell

  2. Создать XYTableViewCellDelegate протокол в вашем TableViewCell.swift файл

  3. Определите делегата вашего предыдущего созданного TableViewCell делегировать в вашем TableViewCell учебный класс

  4. Определите вашего делегата в cellForRowAt: функция вашего стола

  5. Добавьте делегата в ваш класс ViewController, где также реализован TableView

  6. Наконец, просто создайте эту функцию в вашем ViewController, чтобы получить нажатие кнопок tablep 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)
  }
}

Я никогда не пользовалась tableview.indexPathForSelectedRow (и хотя я считаю, что это нехорошая практика, я не уверен, отвечает ли она за вашу проблему), однако вы можете попробовать еще один подход - отправить indexPath объект как sender, Это позволит избежать проверки tableview.indexPathForSelectedRow внутри prepareForSegue, Например,

  • Вы можете вызвать "playDrill" перейти в tableView(UITableView, didSelectRowAt: IndexPath) где у вас есть доступ к этому indexPath и может просто передать его как sender,
  • При запуске вашего "Tips" Segue, вы также можете передать это indexPath объект как отправитель Один из способов получить ссылку - это сохранить indexPath объект, когда вы снимаете свою клетку и устанавливаете действие кнопки в ableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath)

Дайте мне знать, если это поможет вам! Ура,

Julien

Другие вопросы по тегам