Ios Swift/XCode-为什么可以';按下tableViewCell时,是否将数据传递给下一个视图控制器?

Ios Swift/XCode-为什么可以';按下tableViewCell时,是否将数据传递给下一个视图控制器?,ios,swift,uitableview,uiviewcontroller,Ios,Swift,Uitableview,Uiviewcontroller,如果这已经在其他地方得到了回答,我表示歉意——过去两个小时我用类似的建议尝试了不同的事情,但我仍然无法解决它 基本上,我有一个自定义单元格的UITableView(用于不同的测验主题),按下时,应该允许应用程序转到下一个VC并传递一个整数,以便下一个VC知道加载哪个测验。在我的表视图VC中,我有: func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { rowPressed = i

如果这已经在其他地方得到了回答,我表示歉意——过去两个小时我用类似的建议尝试了不同的事情,但我仍然无法解决它

基本上,我有一个自定义单元格的UITableView(用于不同的测验主题),按下时,应该允许应用程序转到下一个VC并传递一个整数,以便下一个VC知道加载哪个测验。在我的表视图VC中,我有:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {


    rowPressed = indexPath.row
    print ("rowPressed = \(rowPressed) before VC changes")

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.destination is GameVC {
        let vc = segue.destination as? GameVC
        vc?.toPass = rowPressed
        print("I ran...")
    } else {
        print("You suck")
    }
var toPass = Int()

override func viewDidLoad() {
    super.viewDidLoad()


    print("toPass = \(toPass)")
在我的游戏VC中,我有:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {


    rowPressed = indexPath.row
    print ("rowPressed = \(rowPressed) before VC changes")

}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if segue.destination is GameVC {
        let vc = segue.destination as? GameVC
        vc?.toPass = rowPressed
        print("I ran...")
    } else {
        print("You suck")
    }
var toPass = Int()

override func viewDidLoad() {
    super.viewDidLoad()


    print("toPass = \(toPass)")
运行时的控制台输出如下所示:

I ran...
toPass = 0
rowPressed = 3 before VC changes
因此,看起来VC在前一个可以发送正确的toPass值之前进行了更改。我该如何解决这个问题


非常感谢

根据序列描述:

例如,如果segue源于表视图,那么sender参数将标识用户点击的表视图单元格

因此,发送方是一个
UITableViewCell
,您可以执行以下操作:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard let cell = sender as? UITableViewCell else { return }
    guard let idx = tableView.indexPath(for: cell) else { return }
    guard let vc = segue.destination as? GameVC else { return }
    vc.toPass = idx.row
}

代码的问题是,根据segue说明,在调用tableView(didSelectRowAt:)之前调用了
prepare(segue:)

例如,如果segue源于表视图,那么sender参数将标识用户点击的表视图单元格

因此,发送方是一个
UITableViewCell
,您可以执行以下操作:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard let cell = sender as? UITableViewCell else { return }
    guard let idx = tableView.indexPath(for: cell) else { return }
    guard let vc = segue.destination as? GameVC else { return }
    vc.toPass = idx.row
}

您的代码的问题是在
tableView(didSelectRowAt:)
之前调用了
prepare(segue:)
,,建议您调用performsgue方法:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    // not necessary 
    //rowPressed = indexPath.row
    //print ("rowPressed = \(rowPressed) before VC changes")

    performSegueWithIdentifier("Your id", sender: indexPath)
    //You can set the identifier in the storyboard, by clicking on the segue
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "Your id"{
        var vc = segue.destinationViewController as! GameVC
        vc.toPass = (sender as! IndexPath).row
    }
}

正如建议的那样,您必须调用performsgue方法:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    // not necessary 
    //rowPressed = indexPath.row
    //print ("rowPressed = \(rowPressed) before VC changes")

    performSegueWithIdentifier("Your id", sender: indexPath)
    //You can set the identifier in the storyboard, by clicking on the segue
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "Your id"{
        var vc = segue.destinationViewController as! GameVC
        vc.toPass = (sender as! IndexPath).row
    }
}

由于在
didSelectRowAt
之前调用了
prepareForSegue
,因此您也可以从情节提要中删除segue,按住ctrl键从顶部的
UITableViewController
黄色图标拖放到第二个
ViewController
,单击segue,给它一个标识符,现在您可以调用
performsgue

override func tableView(tableView:UITableView,didSelectRowAt indepath:indepath){
self.pressed=indexPath.row
self.performsgue(带标识符:“segue identifier”,发送方:nil)
}

因为在
didSelectRowAt
之前调用了
prepareForSegue
,所以您也可以从情节提要中删除segue,按住ctrl键从顶部的
UITableViewController
黄色图标拖放到第二个
ViewController
,单击segue,给它一个标识符,现在您可以调用
performsgue

override func tableView(tableView:UITableView,didSelectRowAt indepath:indepath){
self.pressed=indexPath.row
self.performsgue(带标识符:“segue identifier”,发送方:nil)
}

@Ryan,但在ViewDid中toPass仍然为0。如何让它将正确的toPass传递给GameVC?感谢您的输入。因此,在脚本视图中将segue ID设置为toGameVC之后,我调用performsgue(标识符为:“toGameVC”,发送者:Any?)。然后如何传递toPass数据?我已经在didSelectRowAt函数中添加了performSegue行,首先使用
guard
确保
vc
不是可选的,然后再次赋值。否则,您的序列标识符可能会有输入错误,并且您的
vc
变量为零。谢谢Marc-虽然不太确定您的意思-您能给我举个例子吗?@Ryan,但在ViewDidEmbeen中toPass仍然是0。如何让它将正确的toPass传递给GameVC?感谢您的输入。因此,在脚本视图中将segue ID设置为toGameVC之后,我调用performsgue(标识符为:“toGameVC”,发送者:Any?)。然后如何传递toPass数据?我已经在didSelectRowAt函数中添加了performSegue行,首先使用
guard
确保
vc
不是可选的,然后再次赋值。否则,您的序列标识符可能会有一个输入错误,并且您的
vc
变量为零。谢谢Marc-虽然不太确定您的意思-您能给我举个例子吗?这就成功了谢谢!我将控件从第一个VC顶部的黄色图标拖动到GameVC,然后按照您的指示进行操作。谢谢大家的帮助!这就成功了谢谢你!我将控件从第一个VC顶部的黄色图标拖动到GameVC,然后按照您的指示进行操作。谢谢大家的帮助!