【问题标题】:Sending data to a new view controller through didselectrowatindexpath通过 didselectrowatindexpath 将数据发送到新的视图控制器
【发布时间】:2016-05-03 10:59:36
【问题描述】:

我在一个视图控制器中设置了一个 tableview,我正在尝试将 indexPath.row 文本发送到新视图控制器的标签。我收到一个错误,说它在展开可选值时发现 nil。如果我在下面显示的 viewController 代码中打印“selectedClass”,我会得到 indexPath.row 的文本。如果我在新的 viewController 中打印文本,我什么也得不到。这是我的代码:


覆盖 func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    let classIndexPath = tableView.indexPathForSelectedRow!

    let selectedCell = tableView.cellForRowAtIndexPath(classIndexPath)! as UITableViewCell


    let spinningActivity = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
    spinningActivity.labelText = "Just a Moment"

    if reachabilityStatus == kNOTREACHABLE {

        spinningActivity.hide(true)

        self.displayAlert("No Internet Connection", message: "Please connect to the internet before continuing.")


    } else {

        spinningActivity.hide(true)

        let selectedClass = selectedCell.textLabel!.text!

        let newCardSetVC = self.storyboard?.instantiateViewControllerWithIdentifier("NewCardSetViewController") as! NewCardSetViewController

        newCardSetVC.selectedClassLabel.text = selectedClass as String



        self.performSegueWithIdentifier("addCardSetSegue", sender: self)


    }

}

【问题讨论】:

  • 您正在创建NewCardSetViewController 的新实例并同时使用segue。这真的是你想要的吗?
  • Eendje 所说的。你没有使用你创建的 newCardSetVC 实例?
  • self.presentViewController(newCardSetVC, animated: true, completion: nil)
  • 您也可以调用performSegueWithIdentifier,然后在prepareForSegue 中执行将 selectedClass 值传递给 VC 的所有逻辑
  • 你可能不应该这样做,你会创建一个 NewCardSetVC 的新实例,并使用 segue。这可能就是您遇到此问题的原因。尝试使用prepareForSegue 方法传递您需要的文本信息

标签: swift


【解决方案1】:

大概是这样的……

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if segue.identifier == "segID" {

    let navigationController = segue.destinationViewController as! UINavigationController
    let controller = navigationController.topViewController as! NewCardSetViewController
    let selectedCell = tableView.cellForRowAtIndexPath(indexPathForSelectedRow)! as UITableViewCell
    let selectedClass = selectedCell.textLabel!.text!
    newCardSetVC.selectedClassLabel.text = selectedClass as String
        }
  }

你可以使用
self.performSegueWithIdentifier("addCardSetSegue", sender: self)

在你的didSelectRowAtindexPath

如果您的 NewCardSetViewController 没有嵌入到导航控制器中,您可以跳过上面的一行并直接使用...

let controller = segue.destinationViewController as! NewCardSetViewController

【讨论】:

    【解决方案2】:

    您正在尝试在NewCardSetViewController 的标签中设置字符串值。

    NewCardSetViewController 只会在执行 segue 后加载到内存中。 所以,NewCardSetViewController 的 viewDidLoad() 会在 segue 之后调用。

    在您的代码中,您尝试在 segue 执行之前设置值。 要在 nextViewController 中传递数据,您需要创建具有与您尝试传递的数据相同的数据类型的变量。

    在您的情况下,在NewCardSetViewController 中创建字符串变量strSelectedClass,而不是直接将值设置为标签,而是设置该变量的值,即strSelectedClass

    换行

    newCardSetVC.selectedClassLabel.text = selectedClass as String
    

    newCardSetVC.strSelectedClass = selectedClass as String
    

    NewCardSetViewControllerviewDidLoad: 中放入下面的行,它将在您的标签上显示值。

    self.selectedClassLabel.text = self.strSelectedClass
    

    你已经创建了对象,所以NewCardSetViewController的所有变量都会获得内存,但IBOutlet不会。

    IBOutlet 只会在 segue perform 或 pushViewController 后获取内存。

    【讨论】:

      【解决方案3】:

      试试这样的:

      override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
      
          let classIndexPath = tableView.indexPathForSelectedRow!
          let selectedCell = tableView.cellForRowAtIndexPath(classIndexPath)! as UITableViewCell
          let spinningActivity = MBProgressHUD.showHUDAddedTo(self.view, animated: true)
          spinningActivity.labelText = "Just a Moment"
          if reachabilityStatus == kNOTREACHABLE {
              spinningActivity.hide(true)
              self.displayAlert("No Internet Connection", message: "Please connect to the internet before continuing.")
      
          } else {
              spinningActivity.hide(true)
              self.performSegueWithIdentifier("addCardSetSegue", sender: self)
          }
      }
      
      
      override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
          if segue.identifier == "addCardSetSegue"{
              if let indexPath = tableView!.indexPathForSelectedRow as NSIndexPath?{
                   let selectedCell = tableView?.cellForRowAtIndexPath(indexPath)
                   let selectedClass = selectedCell.textLabel!.text!
                   let vc = segue.destinationViewController as! NewCardSetViewController
                   vc.selectedClassLabel.text = selectedClass as String
              }
          }
      }
      

      因此,当您performSegueWithIdentifier 时,您正在创建一个实例(如果该 VC),而不是使用您在 didSelectRowAtIndexPath 中创建的实例。所以解决方案是改用 performSegue 创建的实例。这是通过在prepareForSegue 中调用segue.destinationViewController 来完成的。

      正如我在 cmets 中所说的那样,替代解决方案可能不是调用 performSegueWithIdentifier 而是调用类似 self.presentViewController(newCardSetVC, animated: true, completion: nil) 的东西。

      希望对您有所帮助,如果您有任何问题,请告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多