XYD
XYD

Reputation: 683

Assign UITableView content to prepare segue in Swift iOS

I faced an issue when trying to build a tableView and use a segue to prepare the next UIViewController screen.

So, from screen A to screen B, on screen B I need to display the info that will be determined by the data user pressed on screen A.

Here is the code in screen A the ViewController:

extension VehicleListToInsureViewController: UITableViewDelegate {
    
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        //print(vehicleList[indexPath.row].vehicleName)
        performSegue(withIdentifier: Constants.segueVehicleListToPolicyList, sender: self)
    
        tableView.deselectRow(at: indexPath, animated: true)
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        let destinationVC = segue.destination as! PolicyOptionsViewController
        destinationVC.vehicleName = vehicleList[indexPath.row].vehicleName
        
    }
    
}

I use an extension to use the UITableViewDelegate, but this line:

destinationVC.vehicleName = vehicleList[indexPath.row].vehicleName

throws errors:

indexPath is unresolved identifier...

How can I fix it? I know it's two functions, that's why I can't use indexPath, but how can resolve this problem to get the data from vehicleList?

Upvotes: 1

Views: 259

Answers (2)

Sweeper
Sweeper

Reputation: 270758

You can pass to the index path (or whatever else you want, really) to prepareForSegue via the sender parameter:

performSegue(withIdentifier: Constants.segueVehicleListToPolicyList, 
             sender: indexPath) // <---- !!

In prepareForSegue, you can try to cast the sender to IndexPath:

if let destinationVC = segue.destination as? PolicyOptionsViewController,
   let indexPath = sender as? IndexPath {
   destinationVC.vehicleName = vehicleList[indexPath.row].vehicleName
}

Alternatively, directly pass vehicleList[indexPath.row].vehicleName as the sender, and cast to String:

performSegue(withIdentifier: Constants.segueVehicleListToPolicyList, 
             sender: vehicleList[indexPath.row].vehicleName)
// ...
if let destinationVC = segue.destination as? PolicyOptionsViewController,
   let vehicleName = sender as? String {
   destinationVC.vehicleName = vehicleName
}

Upvotes: 2

vadian
vadian

Reputation: 285039

Rather than connecting the segue from the controller connect it from the table view cell to the destination controller.

The benefit is you can delete

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //print(vehicleList[indexPath.row].vehicleName)
    performSegue(withIdentifier: Constants.segueVehicleListToPolicyList, sender: self)

    tableView.deselectRow(at: indexPath, animated: true)
}

When prepare(for is called the sender parameter contains the cell and you can ask the table view for its index path

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard segue.identifier == Constants.segueVehicleListToPolicyList,
          let cell = sender as? UITableViewCell,
          let indexPath = tableView.indexPath(for: cell) else { return }
    
    let destinationVC = segue.destination as! PolicyOptionsViewController
    destinationVC.vehicleName = vehicleList[indexPath.row].vehicleName
    
}

Upvotes: 2

Related Questions