iOS Segue not working as expected when passing value - ios

I have a button with the following code:
#IBAction func buttonPress(sender: AnyObject) {
performSegueWithIdentifier("newAccount", sender: sender)
}
When the button is pressed it performs a segue. I want to pass a value to the new view controller so I added the following code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "newAccount" {
if let dvc = segue.destinationViewController as? NewAccountViewController {
dvc.testValue = "This is my test value I want to pass"
}
}
}
The NewAccountViewController doesn't receive the value (I don't get any error).
The code I have in my NewAccountViewController is:
var testValue:String?
When I print(testValue) I don't get anything.
Why isn't this working as expected?

You need to check if the class is set correctly
Like the ViewController in below image

There are maybe two reasons: 1. identifier is not set as "newAccount" in the storyboard; 2. you have put a navigator view controller into the NewAccountViewController, which would ask you to transfer the destination as UINavigationController instead of NewAccountViewController. Hope this helps.

Related

prepare segue - destination View Controller is called twice

In Xcode 13.1 I programmed the following code into my source view controller. It's working so well that it's calling the destination view controller twice (instead of once).
This is my code:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "goToNextViewControllerSegue" {
let destVC = segue.destination as! DestinationViewController
destVC.categoryTag = tag
}
}
Any idea what I'm doing wrong?
Let me include the IBAction code as well (This doesn't seem to be the problem, though.)
#IBAction func startButtonTapped(_ sender: UIButton) {
if tag == 1 || tag == 2 {
self.performSegue(withIdentifier: "goToNextViewControllerSegue", sender: nil)
} else {
createAlert()
}
}
Thanks for any help!
Add a breakpoint to prepare(for segue: sender:) and look at the backtrace to see where it is being called from. My guess is that you have connected the button to the segue in the storyboard, and then also to the action method mentioned in your question, so the segue is being performed twice.

Programmatic embed segue

I'm using a Page View Controller to implement an image carousel in my app. I have a container view in my parent view controller which has an embed segue to the Page View Controller. The problem I'm having is when I need to go off and fetch these images asynchronously and the segue happens before viewDidLoad gets the images.
My prepare for segue:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "startCarousel" {
let carouselPageViewController = segue.destination as! CarouselPageViewController
carouselPageViewController.images = carouselImages
}
}
in viewDidLoad:
GalleryManager.sharedInstance.getData = {
(data) in
// Assign images to instance property here ...
}
My thinking is that once I get the images that I programmatically start the segue myself. Or if I should be doing this a different way any advice would be much appreciated.
You can do something like, return false in shouldPerformSegue and initiate segue when data is loaded
i.e.
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "startCarousel" {
return (detail != nil)
}
return true
}
Then in viewDidLoad
GalleryManager.sharedInstance.getData = { [weak self]
(data) in
self?.performSegue(withIdentifier: "startCarousel", sender: nil)
}
No, you can't delay an embed segue. If you use an embed segue it fires as soon as the view controller is loaded.
You need to wait until the data loads and then call the setViewControllers(direction:animated:completion) to install the view controllers that you will use to display the data once the data is loaded.
Swift 3, Xcode 8
You can realize in this way:
set a reference to your page view controller in prepareForSegue in your masterViewController:
var myContainerViewController: UIPageViewController?
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
if segue.identifier == "embedSegue" {
if let destination = segue.destination as? YourPageViewControllerClass {
self.myContainerViewController = destination
}
}
Define a function in your own pageViewController class:
func someFunction(){
//configure your image or swipe page
}
when you get the images, in your masterViewController call:
self.myContainerViewController?.someFunction()
you can't delay an embed segue.
you try to put button in view controller and then after view load set button click to set image...

How can i create a segue that pass data to another view controller only if certain criteria are met

I want to create a segue to pass data to another view controller but there are certain criteria that must happen for the segue to happen. If possible i would prefer to use the segue Id instead of the dragging method.
this is an example Im trying to accomplish
#IBAction func SubmitButtonPressed(sender: AnyObject) {
if 1<0 {
// dont perform segue
}else{
//Perform segue
// i want to pass this data in the next VC
var data = "foo"
//this is my segue id i want o use to go to the Second VC
var segueId = "segueForgotPasswordTwo"
// second VC
var secondVc = "viewController2"
// Iwant to to use prepare for segue but im getting errors in the parameters
prepareForSegue(UIStoryboardSegue, sender: AnyObject?){
}
}
}
Your question is a bit unclear but I believe this is what you are looking for...
func someFunction(){
if //some condition {
//code
}else if //some condition {
//code
} else {
//perform segue by using the folowing line. Assign the identifier to the segue in the storyboard.
//Do this by first creating a segue by dragging from a view controller to the destination view controller. Be sure to drag from the VIEWCONTROLLER, to the destination VIEWCONTROLLER. DO NOT just drag from the button. Next, choose the type of segue (eg. show or present modally), and then type in an indentifier for this segue.
performSegueWithIdentifier("SegueIdentifier", sender: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "SegueIdentifier" {
//now find your view controller that you are seguing to.
let controller = segue.destinationViewController as! SomeViewController
//access the properties of your viewController and set them as desired. this is how you will pass data along
controller.property = someValue
}
}
Overview:
Hook the segue from the source view controller to the destination view controller (see left side red arrows)
Don’t hook it from the button to the destination view controller
Create an action for the button to do your custom condition check then perform segue
Screenshot:
Code:
var data = "foo"
#IBAction func buttonPressed(sender: UIButton) {
let someCondition = true
if someCondition {
performSegueWithIdentifier("showGreen", sender: self)
}
else {
performSegueWithIdentifier("showPink", sender: self)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showGreen" {
let greenVC = segue.destinationViewController as! GreenViewController
// Make sure the data variable exists in GreenViewController
greenVC.data = data
}
}
You can implement the shouldPerformSegueWithIdentifier function in your ViewController. When the segue is triggered, this function can cancel the segue if it returns false, so you can simply include whatever logic is required in this function and return true/false as appropriate.

How to specify which view controller you are preparing for with Swift's prepareForSegue function?

So I have multiple buttons on one view segue'ing to other views. I have the function prepareForSegue() at the bottom of my code preparing one segue, however the app crashes when I use another segue on the view, even if it doesn't need any preparing.I think that the problem is that all of the segues use the prepareForSegue() function, however the storyboard ID is different than the view it is transitioning to.Is there any way to specify a prepareForSegue() function for each separate segue on the same view?Code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let theVC: ViewController = segue.destinationViewController as! ViewController
theVC.receivedString = "true"
}
Thanks
In your prepareForSegue you should use a condition to check segue identifier like:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "yourSegueToAnyController")
{
//do code for specific viewController
}
}

Navigation Between Two View Controller

I have two View Controllers. in mainViewController there is TabBarButton when it clicked user goes to 1stViewController and there is UIButton when it has clicked user goes to 2ndViewController.
before making my 2ndViewController everything worked fine. but after i add segue function in my program i got error.
could not cast value of type 'Calculator.1stViewController' (0x791a8) to 'Calculator.2ndViewController' (0x794c8).
briefly my code is
#IBAction func CalculateGpa(){
//Calucation Goes Here
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var AnotherName : 2ndViewController = segue.destinationViewController as! 2ndViewController
//Code here
}
UIButton Perform the segue and BarButton do nothing it just go to 1stView Controller. when i run the program and click BarButton im getting that above error.
its because prepareForSegue cant identify to which button it should perform right? how to solve it?
try this code.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if (segue.identifier == "youridentifiername") {
//your class name
if let viewController: DealLandingViewController = segue.destinationViewController as? DealLandingViewController {
viewController.dealEntry = deal
}
}
}

Resources