lifewithelliott lifewithelliott - 3 months ago 41
Swift Question

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?

Answer

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