Swift/XCode - 为啥我不能在按下 tableViewCell 时将数据传递给下一个视图控制器?

Posted

技术标签:

【中文标题】Swift/XCode - 为啥我不能在按下 tableViewCell 时将数据传递给下一个视图控制器?【英文标题】:Swift/XCode - Why can't I pass data to the next view controller when a tableViewCell is pressed?Swift/XCode - 为什么我不能在按下 tableViewCell 时将数据传递给下一个视图控制器? 【发布时间】:2017-10-26 20:37:44 【问题描述】:

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

基本上,我有一个带有自定义单元格(用于不同的测验主题)的 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")
    

在我的 GameVC 中我有这个:

var toPass = Int()

override func viewDidLoad() 
    super.viewDidLoad()


    print("toPass = \(toPass)")

运行时的控制台输出是这样的:

I ran...
toPass = 0
rowPressed = 3 before VC changes

所以看起来 VC 在前一个可以发送正确的 toPass 值之前发生了变化。我该如何解决这个问题?

非常感谢!

【问题讨论】:

@Ryan 但 toPass 在 vi​​ewDidAppear 中仍然为 0。如何让它将正确的 toPass 传递给 GameVC? 感谢您的意见。所以我调用 performSegue(withIdentifier: “toGameVC”, sender: Any?) 在情节提要视图中将 segue ID 设置为 toGameVC。然后如何传递 toPass 数据?我已将 performSegue 行添加到 didSelectRowAt 函数 首先通过使用guard 确保vc 不是可选的,然后再次分配该值。否则,您的 segue 标识符可能有错字,并且您的 vc 变量为零。 谢谢 Marc——虽然不太清楚你的意思——你能给我举个例子吗? 【参考方案1】:

根据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

你的代码的问题是prepare(segue:)tableView(didSelectRowAt:)之前被调用。

【讨论】:

【参考方案2】:

按照建议,您必须调用 performSegue 方法:

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
    

【讨论】:

这成功了,谢谢!我将控件从第一个 VC 顶部的黄色图标拖到 GameVC 上,然后按照您的说明进行操作。感谢大家的帮助!【参考方案3】:

因为prepareForSeguedidSelectRowAt之前被调用,你也可以从Storyboard中去掉segue,按住ctrl从UITableViewController顶部的黄色图标拖放到第二个ViewController,点击segue,给它一个标识符,所以现在你可以调用performSegue

 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    self.pressed = indexPath.row
    self.performSegue(withIdentifier: "segue identifier", sender: nil)

【讨论】:

以上是关于Swift/XCode - 为啥我不能在按下 tableViewCell 时将数据传递给下一个视图控制器?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 UIButton 在按下时有时不会立即做出反应?

为啥在按下 Alt 之前我的 AfxMessageBox 是不可见/隐藏的?

在android中,为啥我的服务在按下电源按钮后没有进入睡眠状态

WPF Focused Visual State 仅在按下按钮时才会启动,为啥?

为啥鼠标右键单击在按下时会触发“pointerdown”事件,但在释放时不会触发“pointerup”事件?

如果第一次从 App Manager 运行应用程序,为啥 Android 在按下 Home 按钮后不保留应用程序状态?