[英]How to get selected table view cell row in segue?
I am developing an iOS app using Swift and I have a view controller that segues from a table view cell content view by selecting a cell row or selecting a button inside of that cell row's content view. 我正在使用Swift开发iOS应用,并且我有一个视图控制器,可以通过选择单元格行或选择该单元格行内容视图中的按钮来从表视图单元格内容视图中筛选。 The original view controller that contains the table view performs a segue on two different occasions: one segue when the cell row itself is selected (segues to an avplayerviewcontroller and plays a video depending on the cell row that was selected) and the second segue happens when you press a button that is inside of the content view of the table view cell.
包含表格视图的原始视图控制器在两种不同的情况下执行segue:一种是在选中单元格行本身时进行segue(与avplayerviewcontroller进行segue,并根据所选的单元格行播放视频),第二种则是在以下情况下发生您按下表视图单元格的内容视图内部的按钮。 In the first segue, I am able to pass the the cell row that is selected with
if let indexPath = self.tableview.indexPathForSelectedRow
when I override the first segue. 在第一个segue中,当我覆盖第一个segue时,
if let indexPath = self.tableview.indexPathForSelectedRow
,我可以传递所选的单元格行。 However when I try to pass the cell row that was selected when I try to override the second segue that happens when you press the button it doesn't work. 但是,当我尝试传递当我尝试覆盖按下按钮时发生的第二次segue时所选的单元格行时,它将不起作用。 Is this because the button inside of the table view cell doesn't know which row it was selected in?
这是因为表格视图单元格内的按钮不知道在其中选择了哪一行? If so, how can I solve this problem, and if not what is a viable solution to solve such issue?
如果是的话,我该如何解决这个问题,如果没有,什么可行的解决方案呢? Reminder: The "playDrill" segue is trigged when you select a cell row, the "Tips" segue is trigged when you selected a button inside of that same cell row's content view
提醒:当您选择一个单元格行时,将触发“ playDrill”序列,而当您在同一单元格行的内容视图中选择一个按钮时,将触发“提示”序列
Code for first segue that happens when you select a cell row (this segue functions as desired): 选择单元格行时发生的第一次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()
}
Code for second segue that triggers when you select a button inside of the cell's content view (I want this segue to have the value of indexPath
as in the first segue, but when I try to use that code it doesn't return the correct value): 当您在单元格的内容视图中选择一个按钮时触发的第二个segue的代码(我希望该segue具有与第一个segue一样的
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
}
}
}
}
I had this issue also a couple of months ago... finally I was able to solve it with the following tasks: 几个月前我也遇到了这个问题...终于,我可以通过以下任务解决这个问题:
Create an Outlet and Action of the button in your corresponding TableViewCell
在相应的
TableViewCell
创建按钮的Outlet和Action
Create a XYTableViewCellDelegate
protocol in your TableViewCell.swift
file 在
TableViewCell.swift
文件中创建XYTableViewCellDelegate
协议
Define a delegate of your previous created TableViewCell
delegate in your TableViewCell
class 在
TableViewCell
类中定义先前创建的TableViewCell
委托的委托
Define your delegate in cellForRowAt:
function of your tableview 在表
cellForRowAt:
函数中定义您的委托
Add the delegate to your ViewController class where the TableView is also implemented 将委托添加到还实现TableView的ViewController类中
Finally just create this function in your ViewController to receive the tapped buttons tableview indexpath 最后,只需在ViewController中创建此函数即可接收点击的按钮tableview indexpath
If you need more help on this, please just copy / paste your whole ViewController & TableViewCell class here - We can make then the changes directly in the code. 如果您需要更多帮助,请在此处复制/粘贴整个ViewController&TableViewCell类-我们可以直接在代码中进行更改。
It should look like the following code: 它应类似于以下代码:
// 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)
}
}
I have never used tableview.indexPathForSelectedRow
(and while I think it is not good practice, I am not sure if it is responsible for your issue), however one other approach you might try is to send the indexPath
object as sender
. 我从未使用过
tableview.indexPathForSelectedRow
(虽然我认为这不是一个好习惯,但是我不确定它是否对您的问题负责),但是您可以尝试的另一种方法是将indexPath
对象作为sender
。 This would avoid having to check for tableview.indexPathForSelectedRow
inside prepareForSegue
. 这样可以避免必须检查
prepareForSegue
tableview.indexPathForSelectedRow
。 For instance, 例如,
"playDrill"
segue in tableView(UITableView, didSelectRowAt: IndexPath)
where you have access to this indexPath
and can simply pass it as sender
. tableView(UITableView, didSelectRowAt: IndexPath)
中触发"playDrill"
tableView(UITableView, didSelectRowAt: IndexPath)
在此您可以访问此indexPath
并可以将其作为sender
传递。 "Tips"
segue, you can also pass this indexPath
object as sender. "Tips"
segue时,还可以将此indexPath
对象作为发送者传递。 One way to have a reference is to keep the indexPath
object when you dequeue your cell and set the button action in ableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath)
ableView(UITableView, willDisplay: UITableViewCell, forRowAt: IndexPath)
设置按钮操作时保留indexPath
对象。 Let me know if that helps you! 让我知道这是否对您有帮助! Cheers,
干杯,
Julien 朱利安
You are not able to get the selected index of the selected cell because you are not actually selecting a cell . 您无法获得所选单元格的所选索引,因为您实际上并未选择单元格 。 You are pressing a button inside the cell.
您正在按单元格内的按钮。
So, what you do is get a reference to the button, get the button's superview (the cell) and then you can get the indexPath
of that cell. 因此,您要做的就是获取按钮的引用,获取按钮的
indexPath
视图(单元格),然后可以获取该单元格的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)
}
Then in prepare(for segue:)
然后
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
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.