Prepare for segue inside of for loop - ios

I have a table view with the following willSelectRowAt code:
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
for n in 0...carsArray.count - 1 {
if indexPath.row == n {
print(carsArray[n].name)
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditCar" {
let name = carsArray[n].name
print(name)
let indexCar = n
let destinationVC = segue.destination as! EditCarViewController
destinationVC.name = name
destinationVC.indexCar = indexCar
}
}
performSegue(withIdentifier: "goToEditCar", sender: self)
}
}
}
Somehow the prepare function won't pass the desired data, neither will it print(name) - can anyone tell me the issue with this piece of code?

Your code cannot work at all. You are using the wrong API, prepare(for is never going to be called inside another method and actually you don't need a loop.
willSelectRowAt is to control if a cell is allowed to be selected. Return the indexPath if it's allowed otherwise return nil
This is not what you want. Use didSelect and pass the index path as sender when calling performSegue
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "goToEditCar", sender: indexPath)
}
In prepare(for get the index path from the sender parameter
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditCar" {
let indexPath = sender as! IndexPath
let name = carsArray[indexPath.row].name
print(name)
let destinationVC = segue.destination as! EditCarViewController
destinationVC.name = name
destinationVC.indexCar = indexPath.row
}
}

You don't need a for-loop here as n eventually will be equal to indexPath.row also you should use didSelectRowAt
func tableView(_ tableView: UITableView,didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "goToEditCar", sender:indexPath.row)
}
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToEditCar" {
let index = sender as! Int
let destinationVC = segue.destination as! EditCarViewController
destinationVC.name = carsArray[index].name
destinationVC.indexCar = index
}
}

Related

Pass var from selected TableView Cell Swift Xcode

I'm a beginner in Swift (Xcode) and I need help. I have a tableview and I want to send information from the indexPath.row to a segue.
My script work, but the problem is the data send to my segue is the previous selected row and not the current cell select. Because the function prepare segue is called before the func tableView. That's make 2 days I search and every tutorial give me the same problem.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
jobname = filldata[indexPath.row]
print(jobname)
performSegue(withIdentifier: "jobsegue", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "jobsegue" {
let destVC = segue.destination as! JobNameViewController
destVC.jobname = jobname
}
}
Thank you sooo much for your help!
Try this, this will work fine:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "jobsegue", sender: indexPath.row)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "jobsegue" {
let destVC = segue.destination as! JobNameViewController
destVC.jobname = filldata[sender]
}
}

I need to override a segue function after clicking a

So I have this tableView and I want when clicking a cell it gives me the name of that cell, and I pass it to next view, but the problem is that I need to override segue function inside of the "didselectrowAt" function and that is impossible I guess, any suggestion on how to do this?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
clickedYear = years[indexPath.row]
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let ResumosVC: Resumos2ViewController = segue.destination as! Resumos2ViewController
ResumosVC.Title = clickedYear
}
Two solutions:
Reconnect the segue to the cell (rather than to the controller) and implement
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let cell = sender as? UITableViewCell,
let indexPath = tableView.indexPath(for: cell) else { return }
let resumosVC = segue.destination as! Resumos2ViewController
resumosVC.Title = years[indexPath.row]
}
Call performSegue in didSelect (replace the identifier string with the real value)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "MySegueIdentifier", sender: indexPath)
}
and change prepare(for to
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let indexPath = sender as? IndexPath else { return }
let resumosVC = segue.destination as! Resumos2ViewController
resumosVC.Title = years[indexPath.row]
}
clickedYear is not needed in both cases.
Note: Please conform to the naming convention to name variables with starting lowercase letter.

Performing segue after filtering in uitableview

Im currently creating an app that has a list of locations on a uitableview. There is also a filtering function so that the locations can be filtered based on categories. When not filtering, the uitableviewcell performs the segue when clicked and the correct data gets loaded in the destination viewcontroller. However when I filter tableview, the cells get populated with the right data, but when I click the cell, the destination viewcontroller always loads the data from the first cell in the UNFILTERED tableview.
The code that I am using:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "shoutoutCell", for: indexPath) as! shoutoutTableViewCell
var shout = shoutout[indexPath.row]
if isFiltering == true {
shout = filteredShoutout[indexPath.row]
} else {
shout = shoutout[indexPath.row]
}
cell.shoutout = shout
cell.showsReorderControl = true
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var object = shoutout[indexPath.row]
if isFiltering == true {
object = filteredShoutout[indexPath.row]
} else {
object = shoutout[indexPath.row]
}
performSegue(withIdentifier: "shoutoutDetailSegue", sender: object)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "shoutoutDetailSegue" {
if let destination = segue.destination as? shoutoutDetailViewController {
// destination.shoutoutSelected = sender as! object
destination.shoutoutSelected = shoutout[(tableView.indexPathForSelectedRow?.row)!]
}
}
}
This is happening because you are using shoutout Array in prepare(for segue even when filtering.
destination.shoutoutSelected = shoutout[(tableView.indexPathForSelectedRow?.row)!]
Change it to
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "shoutoutDetailSegue" {
if let destination = segue.destination as? shoutoutDetailViewController {
// Here `Model` should be your class or struct
destination.shoutoutSelected = sender as! Model
}
}
OR move your logic here from didSelectRowAt
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "shoutoutDetailSegue" {
if let destination = segue.destination as? shoutoutDetailViewController {
if isFiltering == true {
object = filteredShoutout[indexPath.row]
} else {
object = shoutout[indexPath.row]
}
destination.shoutoutSelected = object
}
}

Passing data from table view controller to view controller

I'm having issues with moving from a table view controller to a view controller to display information about a particular cell that was selected.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SentDetailView" {
let indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow! as NSIndexPath
let referrals = referralsSent[indexPath.row]
let destViewController = segue.destination as! SentDetailViewController
destViewController.referringTo = referrals.referTo
destViewController.patientsName = referrals.patientsName
//print("Contained value during segue " + destViewController.patientsName!)
destViewController.patientsPhoneNumber = referrals.patientsNumber
destViewController.patientsEmail = referrals.patientsEmail
destViewController.comments = referrals.comment
}
}
Storyboard setup:
I get the following results:
I select a cell and it just highlights and doesn't do anything.
You should override didSelectRowAt and call performSegue with sender as the selected index path. Try this.
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.performSegue(withIdentifier: "SentDetailView", sender: indexPath)
}
And this.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "SentDetailView"{
let indexPath = sender as! IndexPath
let referrals = referralsSent[indexPath.row]
let destViewController = segue.destination as! SentDetailViewController
destViewController.referringTo = referrals.referTo
destViewController.patientsName = referrals.patientsName
//print("Contained value during segue " + destViewController.patientsName!)
destViewController.patientsPhoneNumber = referrals.patientsNumber
destViewController.patientsEmail = referrals.patientsEmail
destViewController.comments = referrals.comment
}
}

Usage of performSeguewithIdentifier Function in Dynamic Values Tableview

I can list datas in tableview. When I choose a row and trying to pass another view controller with showing specific data related to my pressed cell, It couldn't make it.
I didn't able to store data "selectedMeal" variable in prepareforsegue function, it always return [ ].
I think, my main problem is selecting the cell and sending to this cell to prepare for segue function. Perhaps, it has a problem in DispatchQueue.main.async function.
*When I try to pass to static data, it works great.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark;
DispatchQueue.main.async {
self.performSegue(withIdentifier: "gotoOrderDetail", sender: self)
}
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "gotoOrderDetail") {
let DestViewController : OrderDetailListViewController = segue.destination as! OrderDetailListViewController
let selectedMeal = selectedCells.map { (index: Int) -> SavedMeal in
return savedMeal[index]
}
DestViewController.mealarray = selectedMeal
}
}
Try to use this code
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "gotoOrderDetail") {
let DestViewController : OrderDetailListViewController = segue.destination as! OrderDetailListViewController
let path = self.tableView.indexPathForSelectedRow()! // get the selected indexPath
DestViewController.mealarray = savedMeal[path.row]
}
}
Try to use Sender parameter
you can you like this:
self.performSegue(withIdentifier: "gotoOrderDetail", sender: indexPath)
and then in prepare(for segue: sender?)
if (segue.identifier == "gotoOrderDetail") {
let DestViewController : OrderDetailListViewController = segue.destination as! OrderDetailListViewController
let index = sender as! Int
DestViewController.mealarray = savedMeal[index]
}
p/s: you do not need to use dispatch queue in this case

Resources