Passing object with prepareForSegue Swift - ios

I am trying to pass an object to another scene with prepareForSegue()
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using [segue destinationViewController].
var nextScene = segue.destinationViewController as! VehicleDetailsTableViewController
// Pass the selected object to the new view controller.
if let indexPath = self.tableView.indexPathForSelectedRow() {
let selectedVehicle = vehicles[indexPath.row]
nextScene.currentVehicle = selectedVehicle
}
}
And I have currentVehicle object to catch these object. But, when I try to run, it brokes and get error about downcasting.
Error EDIT
Could not cast value of type 'XXX.DisplayViewController'
(0x1082dcd80) to 'XXX.VehicleDetailsTableViewController'
(0x1082dc9a0). (lldb)

You have to give the segue an identifier in the storyboard.(say mySegue)
Using Xcode 10 swift 4.x(Also works with Xcode 9 & 8 , swift 3.x)
override func prepare(for segue: UIStoryboardSegue, sender: Any?){}
Is called for all segues being called from your current UIViewController. So the identifier is to differentiate the different segues
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "mySegue" ,
let nextScene = segue.destination as? VehicleDetailsTableViewController ,
let indexPath = self.tableView.indexPathForSelectedRow {
let selectedVehicle = vehicles[indexPath.row]
nextScene.currentVehicle = selectedVehicle
}
}
If you are using Using Xcode 7, swift 2.x
Then use this code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "mySegue" {
var nextScene = segue.destinationViewController as! VehicleDetailsTableViewController
// Pass the selected object to the new view controller.
if let indexPath = self.tableView.indexPathForSelectedRow {
let selectedVehicle = vehicles[indexPath.row]
nextScene.currentVehicle = selectedVehicle
}
}
}
Place a breakpoint after nextScene and see if it is being triggered by clicking any cell in the TableView. If it isn't then the identifier name u provided in the storyboard must be different then the one given here.

In swift 3.0 Xcode 8 beta 6
AnyObject has been renamed to Any?
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
let nextScene = segue.destinationViewController as! VehicleDetailsTableViewController
// Pass the selected object to the new view controller.
if let indexPath = self.tableView.indexPathForSelectedRow {
let selectedVehicle = vehicles[indexPath.row]
nextScene.currentVehicle = selectedVehicle
}
}
}

In Swift 3, Xcode 8
Just don't use "identifier". I don't know why but "segue.identifier" is always nil. I just used prepare method like this and works!
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let secondController = segue.destination as? SecondController {
secondController.anyItemInSecondController = self.anyItemInFirstController
}

What that error is telling you is that segue.destinationViewController isn't a VehicleDetailsTableViewController. We don't have enough details to tell you why.
Check your segues and make sure they're all pointing to the correct place, and always check the identifier of your segue before you perform a cast.
if segue.identifier == "theNameOfYourSegue" // then do your cast

Related

VC presenter is not being initialized prepare for segue IOS swift

Hello i am facing the problem as the prepare for segue function is not working properly i've the code can you please tell me how can i debug it as it has optional conditions how i can remove them and check what's the problem or what i am doing wrong as i just want a class to be initialized in target vc before the app navigates to other screen.
#IBAction func filterBtnPressed(_ sender: Any) {
self.performSegue(withIdentifier: "FilterSessionVC", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "FilterSessionVC", let navigation = segue.destination as? UINavigationController, let vc = navigation.topViewController as? FilterSessionVC {
vc.presenter = FilterSessionPresenterImplementation()
}
}
Basic debugging...
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let identifier = segue.identifier
print("identifier:", identifier)
let dest = segue.destination
print("destination:", dest)
if let navigation = dest as? UINavigationController {
print("dest IS a UINavigationController")
if let vc = navigation.topViewController as? FilterSessionVC {
print("Top Controller IS a FilterSessionVC")
// here you can proceed
vc.presenter = FilterSessionPresenterImplementation()
} else {
print("Top Controller IS NOT a FilterSessionVC")
}
} else {
print("dest IS NOT a UINavigationController")
}
}
Set a breakpoint on the first line, then step through and inspect the results.

Adding ChildViewControllers Using Storyboard Not Working

I have a Storyboard which is shown below in the screenshot:
From my HomeController I segue to ContainerViewController using the code below. For some reason the childControllers is always nil.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let indexPath = self.tableView.indexPathForSelectedRow else {
fatalError("No row selected")
}
let place = self.places[indexPath.row]
let containerViewController = segue.destination as! ContainerViewController
containerViewController.childViewControllers // THIS IS NIL WHY!!!

Swift Segue not working

I have a school project to make a swift app. I'm very new to swift and trying to pass data through the segue from a tableview to another view.
Here is the project file Download Here.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "PopularDetails" {
let detailsViewController = segue.destinationViewController as DetailsViewController
let selectedIndexPath = popularTableView.indexPathForSelectedRow()
detailsViewController.shots = shots[selectedIndexPath.row]
}
}
}
.indexPathForSelectedRow() returns an optional. You have to unwrap it, before you can access its properties. Try:
let selectedIndexPath = popularTableView.indexPathForSelectedRow()
detailsViewController.shots = shots[selectedIndexPath!.row]
(see the exclamationmark)
Although #gutenmorgenuhu is correct, it's probably better practice to use:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "PopularDetails" {
if let detailsViewController = segue.destinationViewController as? DetailsViewController {
if let selectedIndexPath = popularTableView.indexPathForSelectedRow() {
detailsViewController.shots = shots[selectedIndexPath.row]
}
}
}
}

Swift pass data between VCs

i'm new to Swift and i would like to know why this piece of code i translated from Obj-C doesn't work here.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "scoreDetail" {
let indexPath = self.tableView.indexPathForSelectedRow()
let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject
let itemVC: ScoreVC = segue.destinationViewController as ScoreVC
itemVC.detailItem = object
}
}
Here is the storyboard. I have a Show Replace segue from the cell to the UINavigatorController
I get this error as soon as i click on a UITableViewCell
The problem has nothing to do with Swift. The destinationViewController is the navigation controller, not your ScoreVC, so the code you translated that from shouldn't have worked either (if it had the same setup). It should look like this,
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "scoreDetail" {
let indexPath = self.tableView.indexPathForSelectedRow()
let object = self.fetchedResultsController.objectAtIndexPath(indexPath) as NSManagedObject
let nav : UINavigationController = segue.destinationViewController
let itemVC: ScoreVC = nav.topViewController as ScoreVC
itemVC.detailItem = object
}
}

Prepare for Segue in Swift

I'm facing the error message:
"UIStoryboardSegue does not have a member named 'identifier'"
Here's the code causing the error
if (segue.identifier == "Load View") {
// pass data to next view
}
On Obj-C it's fine using like this:
if ([segue.identifier isEqualToString:#"Load View"]) {
// pass data to next view
}
What am I doing wrong?
This seems to be due to a problem in the UITableViewController subclass template. It comes with a version of the prepareForSegue method that would require you to unwrap the segue.
Replace your current prepareForSegue function with:
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "Load View") {
// pass data to next view
}
}
This version implicitly unwraps the parameters, so you should be fine.
Swift 4, Swift 3
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "MySegueId" {
if let nextViewController = segue.destination as? NextViewController {
nextViewController.valueOfxyz = "XYZ" //Or pass any values
nextViewController.valueOf123 = 123
}
}
}
I think the problem is you have to use the ! to unbundle identifier
I have
override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
if segue!.identifier == "Details" {
let viewController:ViewController = segue!.destinationViewController as ViewController
let indexPath = self.tableView.indexPathForSelectedRow()
viewController.pinCode = self.exams[indexPath.row]
}
}
My understanding is that without the ! you just get a true or false value
For Swift 2.3,swift3,and swift4:
Create a perform Segue at didSelectRowAtindexPath
For Ex:
self.performSegue(withIdentifier: "uiView", sender: self)
After that Create a prepareforSegue function to catch the Destination segue and pass the value:
Ex:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "uiView"{
let destView = segue.destination as! WebViewController
let indexpath = self.newsTableView.indexPathForSelectedRow
let indexurl = tableDatalist[(indexpath?.row)!].link
destView.UrlRec = indexurl
//let url =
}
}
You need to create a variable named UrlRec in Destination ViewController
Swift 1.2
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "ShowDeal") {
if let viewController: DealLandingViewController = segue.destinationViewController as? DealLandingViewController {
viewController.dealEntry = deal
}
}
}
Prepare for Segue in Swift 4.2 and Swift 5.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "OrderVC") {
// pass data to next view
let viewController = segue.destination as? MyOrderDetailsVC
viewController!.OrderData = self.MyorderArray[selectedIndex]
}
}
How to Call segue On specific Event(Like Button Click etc):
performSegue(withIdentifier: "OrderVC", sender: self)
this is one of the ways you can use this function, it is when you want access a variable of another class and change the output based on that variable.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let something = segue.destination as! someViewController
something.aVariable = anotherVariable
}
Provided you aren't using the same destination view controller with different identifiers, the code can be more concise than the other solutions (and avoids the as! in some of the other answers):
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
if let myViewController = segue.destinationController as? MyViewController {
// Set up the VC
}
}
Change the segue identifier in the right panel in the section with an id. icon to match the string you used in your conditional.
override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject?) {
if(segue!.identifier){
var name = segue!.identifier;
if (name.compare("Load View") == 0){
}
}
}
You can't compare the the identifier with == you have to use the compare() method

Resources