Как получить выбранную строку ячейки представления таблицы в 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
}
}
}
У меня была эта проблема также пару месяцев назад... наконец я смог решить ее с помощью следующих задач:
Создайте розетку и действие кнопки в своем соответствующем
TableViewCell
Создать
XYTableViewCellDelegate
протокол в вашемTableViewCell.swift
файлОпределите делегата вашего предыдущего созданного
TableViewCell
делегировать в вашемTableViewCell
учебный классОпределите вашего делегата в
cellForRowAt:
функция вашего столаДобавьте делегата в ваш класс ViewController, где также реализован TableView
Наконец, просто создайте эту функцию в вашем 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