1

I have a tableview set up in one view controller and I am trying to send the indexPath.row text to a new view controller's label. I am getting an error that says it found nil when unwrapping an optional value. If I print "selectedClass" in the viewController code shown below, I get the text of indexPath.row. If I print the text in the new viewController, I get nothing. Here is my code:


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)

        let selectedClass = selectedCell.textLabel!.text!

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

        newCardSetVC.selectedClassLabel.text = selectedClass as String



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


    }

}

Dan Levy
  • 23
  • 6
  • 2
    You're creating a new instance of `NewCardSetViewController` and using a `segue` together. Is that really what you want? – Eendje Jan 26 '16 at 18:42
  • What Eendje said. you are not using the newCardSetVC instance you created? – boidkan Jan 26 '16 at 18:46
  • `self.presentViewController(newCardSetVC, animated: true, completion: nil)` – boidkan Jan 26 '16 at 18:46
  • you could also call `performSegueWithIdentifier` and then in `prepareForSegue` do all the logic of passing the selectedClass value to the VC – boidkan Jan 26 '16 at 18:47
  • You probably shouldn't do this, where you create a new instance of `NewCardSetVC` , and also use a `segue`. That could be why your having this issue. Try using a `prepareForSegue` method to pass along the text info you need – MikeG Jan 26 '16 at 18:48
  • Thanks everyone! I needed to change performSegueWithIdentifier to presentViewController and set selectedClass = selectedClass in the new VC rather than the label. In the new VC, I set selected class = selectedClassLabel. – Dan Levy Jan 26 '16 at 21:49
  • Have a look at SO https://stackoverflow.com/a/53386919/10661965 – iOS_Maccus Nov 21 '18 at 12:36

3 Answers3

0

Try something like this:

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
        }
    }
}

So when you performSegueWithIdentifier you are creating a instance if that VC and not using the instance you created in didSelectRowAtIndexPath. So the solution is to instead use the instance created by performSegue. Which is done by calling segue.destinationViewController in prepareForSegue.

An alternate solutions could be not calling performSegueWithIdentifier and instead calling something like self.presentViewController(newCardSetVC, animated: true, completion: nil) instead as I stated in the comments.

Hope this helps, let me know if you have any questions.

boidkan
  • 4,691
  • 5
  • 29
  • 43
0

Perhaps something like this ...

 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
        }
  }

and you can use
self.performSegueWithIdentifier("addCardSetSegue", sender: self)

in your didSelectRowAtindexPath

if your NewCardSetViewController is not embedded in a nav controller you can skip one of the lines above and go straight to it with...

let controller = segue.destinationViewController as! NewCardSetViewController

MikeG
  • 3,745
  • 1
  • 29
  • 51
0

You are trying to set string value in label of NewCardSetViewController.

NewCardSetViewController will only load in memory after perform segue. So, viewDidLoad() of NewCardSetViewController will call after segue.

In your code you are trying to set value before segue perform. To passData in nextViewController you need to create variable with same dataType of data your are trying to pass.

In your case create string variable in NewCardSetViewController say strSelectedClass, instead of setting value directly to label, set value of that variable i.e. strSelectedClass.

Replace line

newCardSetVC.selectedClassLabel.text = selectedClass as String

with

newCardSetVC.strSelectedClass = selectedClass as String

In viewDidLoad: of NewCardSetViewController put below line, it will display value onto your label.

self.selectedClassLabel.text = self.strSelectedClass

you have created object, so all variable of NewCardSetViewController will get memory, but IBOutlet will not.

IBOutlet will only get memory after segue perform or pushViewController.

Hitendra Solanki
  • 4,871
  • 2
  • 22
  • 29