Swift Prepare(for: segue) not called - swift

In my storyboard controller1 has natigationController and segues to controller 2. It is weird that the Segue works ok but
override func prepare(for: segue)
the whole method was not called (I set breakpoint). I reviewed a lot of old questions on stackoverflow, but no one could solve my problem. Thanks!
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
self.navigationController?.performSegue(withIdentifier: segueId, sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == self.segueId {
let destionationNVC = segue.destination as! UINavigationController
guard let targetVC = destionationNVC.topViewController as? ViewController2 else { return }
targetVC.text = self.text
}
}

You are calling performSegue on self.navigationController, so it's the navigationController.prepareForSegue that will be called, not the one in your VC. You should reconnect the segue to your VC in the storyboard, give it the identifier, and call:
self.performSegue(...)

Related

With swift5 no longer works indexPathForSelectedRow is not recognized by xcode

With swift5 and TableView (no TableViewController), no longer works indexPathForSelectedRow is not recognized by xcode, I don't know what has changed
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "goToItems", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destinationVC = segue.destination as! ViewController2
if let indexPath = tableView.indexPathForSelectedRow {
destinationVC.selectedTable = dataTableWord[indexPath.row]
} else {
}
}
There is no change on the UITableView on swift5 or Xcode.
Make sure that you have defined your UITableView variable correctly.
Or, if you're using storyboard, remove and reconnect your tableView outlet to the UITableView object on the storyboard.

Swift - performSegue causing ViewController to load before prepareForSegue passes data

I'm trying to perform a segue between two table views via tapping on a cell. However it seems performSegue is loading the view before prepareForSegue has passed the data and thus the array is left empty in the second view controller.
Here's the code for my segue:
func prepare(for segue: UIStoryboardSegue, sender: Any?, didSelectRowAt indexPath: IndexPath) {
if let vc = segue.destination as? ModuleTableViewController {
vc.modules = programmes[indexPath.row].modules
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "ProgrammeToggleVCtoModuleVC", sender: self)
}
I'd like to have it pass across the data before the view is loaded, as there is a check in the second VC that causes the programme to crash if the data isn't present.
I've only been doing Swift for the past few weeks so excuse me if I've missed any info, happy to amend it if you need more information.
You need to hook segue from the vc itself not from the cell and correct prepare to
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? ModuleTableViewController {
vc.modules = programmes[tableView.indexPathForSelectedRow!.row].modules
}
}
OR
performSegue(withIdentifier: "ProgrammeToggleVCtoModuleVC", sender: indexPath.row)
with
func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? ModuleTableViewController {
vc.modules = programmes[sender as! Int].modules
}
}

why do I get two consecutive viewcontrollers when carrying out segue to show details

when I click on the uicollectionViewCell then I come to a ViewController that is empty and a split second later a new ViewController is createdvshowing the data correctly. Going back I have to click the back button twice to navigate back to the original viewController. In the MainStoryboard I have a "show detail" segue implemented. What is going on here? What do I have to check?? Here is the code:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath) as! CollectionViewCell
key = cell.keyImage.image
performSegue(withIdentifier: "showKeyDetails", sender:self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showKeyDetails"{
if let destVC = segue.destination as? KeyDetailViewController{
if key != nil{
destVC.key = key
}
}
}
}
You wired your segue from the collectionView cell. So, when you select the cell, a segue fires, and then performSegue creates a second segue.
To fix this, you can either:
Remove the performSegue call, remove the didSelectItem function and update your prepare(for:sender:) function to find the key:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showKeyDetails"{
if let destVC = segue.destination as? KeyDetailViewController,
let cell = sender as? CollectionViewCell,
let key = cell.keyImage.image
{
destVC.key = key
}
}
}
OR:
2) Wire the segue from the viewController icon at the top of the VC instead of from the cell.

PrepareForSegue not sending data between two TableView Controllers

I am trying to pass a test variable to my destination controller, but the test is unsuccessful.
My performsegue is done here:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
programKeySegue = programKeys[indexPath.section]
self.performSegue(withIdentifier: "segueSelectedProgram", sender: self)
}
My prepareforsegue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "segueSelectedProgam" {
let selectedProgramVC = segue.destination as! SelectedProgramTableViewController
selectedProgramVC.programKey = "test" //programKeySegue
}
}
and in the destination controller:
var programKey: String?
But when I print(programKey) in viewDidLoad 'nil' is printed to the console. I have used this method before and it has always worked fine. Can anyone tell me what I did wrong?
I tired removing override from prepare for segue, I tried appending self to the performsegue and I have tried assigning different variables to be passed. Nothing has worked.
As noted in the comments, your problem was caused by a typo. You can prevent this in future by not using string comparison…
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// If there are multiple segues to this destination, you can
// perform a similar check on the source
if let selectedProgramVC = segue.destination as? SelectedProgramTableViewController
selectedProgramVC.programKey = "test" //programKeySegue
}
}
Also, you could give use the view controller name as the segue name in the storyboard, and then…
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
programKeySegue = programKeys[indexPath.section]
self.performSegue(withIdentifier: String(describing: SelectedProgramTableViewController .self), sender: self)
}
et voila… no strings!

Prepareforsegue not passing the appropriate value to destination Viewcontroller?

I have two viewcontrollers (one is tableVC) that I would like to pass information between. Here is code from that tableVC:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var rowSelected = indexPath.row
print(rowSelected) //always returns the correct integer
func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let destViewController: newController = segue.destination as! newController
newController.rowSelected = rowSelected
}
performSegue(withIdentifier: "rowSelected", sender: Any?.self)//segue to newController
}
And here is the code for the newController that I want the info to be passed to:
#IBOutlet weak var label: UILabel!
var rowSelected = Int()
override func viewDidLoad() {
super.viewDidLoad()
label.text = infoArray[rowSelected]
print(rowSelected) //always logs 0 to the console, regardless of cell selection
}
I thought I had set this up appropriately, but for whatever reason the index called to the infoArray is always 0, no matter what cell is selected in the tableVC. Not sure what the problem is.
write prepareForSegue in class scope/global scope. in your code prepareForSegue will never call because you are writing this inside the method. pass rowSelected in performSegue and get rowSelected value in prepareForSegue using sender or you can use indexPathForSelectedRow property of tableView.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
...
performSegue(withIdentifier: "rowSelected", sender: rowSelected)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: Any?) {
let rowSelected = sender as! Int
// or you can use indexPathForSelectedRow for getting row value
// let indexPath = self.tableView.indexPathForSelectedRow?
// let rowSelected = indexPath!.row
let destViewController: newController = segue.destination as! newController
newController.rowSelected = rowSelected
}
Need to use override in your function when you prepareForSegue
See below example code : -
Swift 3
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "ShowAttractionDetails" {
let detailViewController = segue.destination
as! AttractionDetailViewController
let myIndexPath = self.tableView.indexPathForSelectedRow!
let row = myIndexPath.row
detailViewController.webSite = webAddresses[row]
}
}
Swift 2.3
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowAttractionDetails" {
let detailViewController = segue.destination
as! AttractionDetailViewController
let myIndexPath = self.tableView.indexPathForSelectedRow!
let row = myIndexPath.row
detailViewController.webSite = webAddresses[row]
}
}
Source - Segue from UITableViewCell Taps in Swift & TableView Navigation using Storyboards in Xcode 8