Search code examples
swiftuitableviewuiviewcontrollerunwind-seguepass-data

Swift - Unwind segue passes back nil value?


I have two view controllers. The second view controller hosts a table view with a custom cell that unwinds back to the first view controller and sends back the data associated with that cell.

In the second view controller class I implemented didSelectRowAtIndexPath and tested to see if the correct item is stored in a class property. It correctly stores the optional value however when I attempt to use that value in the first view controller the property prints nil to the console.

// First view controller

@IBAction func unwindActivitiesVCCellTapped( segue: UIStoryboardSegue )
{
    // table view cell tapped

    guard let activitiesVC = segue.sourceViewController as? ActivitiesVC else { return }

    print(activitiesVC.activityPerforming) // Displays nil in console output

    if let activityPerforming = activitiesVC.activityPerforming // thus this does not get called
    {
        activityPerformingButton.titleLabel?.text = activityPerforming
    }
}

// Second View Controller

class ActivitiesVC: UIViewController 
{
    @IBOutlet weak var activitiesTableView: UITableView!

    let activityTitles = [ "Walk" , "Run ", "Cycle", "Mountain Bike" ]

    var activityPerforming: String?

    override func viewDidLoad()
    {
        super.viewDidLoad()

        activitiesTableView.dataSource = self
        activitiesTableView.delegate   = self
    }
}

extension ActivitiesVC: UITableViewDelegate
{
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
    {
        activityPerforming = activityTitles[ indexPath.row ]
        print(activityPerfoming) // displays optional value I want
    }
}

// Custom Cell

class ActivityCell: UITableViewCell
{

    @IBOutlet weak var imageLabel    : UILabel!
    @IBOutlet weak var activityLabel : UILabel!

    override func awakeFromNib()
    {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(selected: Bool, animated: Bool)
    {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }
}

What is the reason for the property appearing as nil and what can I do to remedy this situation?


Solution

  • I suspect that your unwind segue is wired directly to your UITableViewCell so it is triggered before didSelectRowAtIndexPath is called.

    To fix this, move the code in didSelectRowAtIndexPath into prepareForSegue:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let indexPath = activitiesTableView.indexPathForSelectedRow {
            activityPerforming = activityTitles[ indexPath.row ]
            print(activityPerfoming) // displays optional value I want
        }
    }