performSegueWithIdentifier doesn't work in a different ViewController - ios

I have the following storyboard: Main Storyboard
In it, several custom View Controllers are programmatically embedded in the Scroll View. In one of them, a button is present and should trigger a segue to show the "hey" screen.
I have then wrote the following code:
#IBAction func addNewDateButtonDidTouched(sender :AnyObject) {
let mainStoryboard = UIStoryboard(name: "Main", bundle: nil)
let storyboardInit = mainStoryboard.instantiateViewControllerWithIdentifier("mainview")
storyboardInit.performSegueWithIdentifier("showNewDate", sender: self)
}
This #IBAction seems to reload the inital view controller and perform the segue correclty (Xcode doesn't return any error). But the "hey" screen doesn't show up and its viewDidLoad() doesn't load.
Any hint?

Instead of calling
storyboardInit.performSegueWithIdentifier("showNewDate", sender: self)
try
self.performSegueWithIdentifier("showNewDate", sender: self)

The storyboardInit in your code will instantiate a UIViewController that has an identifier "mainview".
But this UIViewController hasn't been added to the screen, when you're asking the controller to perform a segue.
So, I wouldn't do that. What I would do, to segue to the hey screen is either :
Create a segue from the current controller and just do this in the code : self.performSegueWithIdentifier
Instantiate the hey controller like this : instantiateViewControllerWithIdentifier, and then just do the self.presentViewController
So, to transition to a new controller, you have to start from the current controller.

if i understand your viewcontroller hierarchy correctly...
since the viewcontroller that contains the button to trigger the segue is a childviewcontroller of the viewcontroller that has the segue setup in storyboard i think you have to call presentingViewController?.performSegueWithIdentifier("showNewDate", sender: self).

Related

How to pass values from a Pop Up View Controller to the Previous View Controller?

So In my 1stViewController I have this code:
#IBAction func colorDropdown(_ sender: Any) {
self.popUpColorPicker()
}
func popUpColorPicker() {
let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ColorPicker") as! ColorPicker
self.addChildViewController(popOverVC)
popOverVC.view.frame = self.view.frame
self.view.addSubview(popOverVC.view)
popOverVC.didMove(toParentViewController: self)
}
Which would pop up the 2ndViewController. Upon dismissing the Pop Up 2ndViewController, I'd like to retrieve the values I entered and use it in my 1st View Controller.
You can achieve this by either using delegate or completion handler.
Just create a delegate to handle your data on dismissing the second VC.
**
OR
**
Write a completion handler closure to get back those values in your first view controller.
Suppose A & B are two controllers and you first navigated from A to B with some data. And now you want to POP from B to A with some data.
Unwind Segues is the best and recommended way to do this.
Here are the steps.
Open A.m
define following method
#IBAction func unwindSegueFromBtoA(segue: UIStoryNoardSegue) {
}
open storyboard
Select B ViewController and click on ViewController outlet. press control key and drag to 'Exit' outlet and leave mouse here. In below image, selected icon is ViewController outlet and the last one with Exit sign is Exit Outlet.
You will see 'unwindSegueFromBtoA' method in a popup . Select this method .
Now you will see a segue in your view controler hierarchy in left side. You will see your created segue near StoryBoard Entry Piont in following Image.
Select this and set an identifier to it. (suggest to set the same name as method - unwindSegueFromBtoA)
Open B.m . Now, wherever you want to pop to A. use
self.performSegueWithIdentifier("unwindSegueFromBtoA", sender: dataToSend)
Now when you will pop to 'A', 'unwindSegueFromBtoA' method will be called. In unwindSegueFromBtoA of 'A' you can access any object of 'B'.
That's it..!
you can always use unwind to do some stuff upon unwinding
declare a IBAction in your first vc
var color: UIColor!
#IBAction func unwindToCheckout(segue: UIStoryboardSegue) {
//do some stuff with color
}
then create exit segue for popout viewcontroller
then you can dismiss popout like this
self.performSegueWithIdentifier("unwindToVC1", sender: selectedColor)
then in prepareForSegue
if segue.identifier == "unwindToVC1" {
(segue.destinationViewController as! FirstViewController).color = sender as! UIColor
}
also you can create delegate to reach fistviewcontroller and do some stuff which is way easier to do

Swift 3 View controller has no segue with identifier

I am trying to get my View controller to perform a segue from my Game Scene class when the node "dies". I have copied and used the following code:
var vc: UIViewController = UIViewController()
vc = self.view!.window!.rootViewController!
vc.performSegue(withIdentifier: "segue", sender: vc)
self.viewController?.performSegue(withIdentifier: "segue", sender: vc)
In my Function. I also added the code to make the Game scene act as the current view controller. I then created a segue named segue from the current view controller to the next view controller but there was an error
FirstMenuViewController has no segue "segue"
Any help would be much appreciated as i have been working on this problem for ages and am on the last resort.

How can I use my action and programmatically transition to a view controller as defined in the storyboard?

I have a sent Action, as follows:
#IBAction func showSettings(sender: AnyObject) {
let settingsPicker = SettingsViewController()
settingsPicker.setDelegate(self)
let navigationController = UINavigationController (rootViewController: settingsPicker)
self.presentViewController(navigationController, animated: true, completion: nil)
}
The method creates a controller, sets a reference to the delegate, and creates a navigation controller.
All this works, however the widgets defined in the story board do not appear. The SettingsViewController should manage a ui which is defined in a story board. I presume becuase I create it programmatically none of the widgets appear. The SettingsViewController does not programmatically create widgets, the are declaratively defined in the story board.
If I link (in the storyboard) the two controllers with a segue, then the widgets appear, but my action is not being used.
How can I use my action and present the view controller / ui as defined in the storyboard?
When you create a segue between your UIViewControllers, you should define an identifier, eg: "settingsSegue".
In your code you can then perform that segue by calling the segue with the identifier:
#IBAction func showSetting(sender: AnyObject) {
performSegueWithIdentifier("settingsSegue", sender: nil)
}
To set up the SettingsViewController you should implement the following:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){
if let settingsController = segue.destinationViewController as? SettingsViewController {
settingsController.delegate = self
}
}
Interacting with Storyboard and Segues
If you want to invoke a segue through code, see Laffen's answer.
If you want to create a view controller that's defined in your storyboard and then display it programmatically, use instantiateViewControllerWithIdentifier to create a new instance of your view controller, then display it to the screen as desired (present it modally, push it onto your navigation stack, or whatever you want to do.)

How to move to existing viewcontroller from another viewcontroller

When I start the app my initial view is MainViewController.
Then on button click I move to AnotherViewController.
performSegueWithIdentifier("myFirstSegue", sender: self)
On AnotherViewController I have a button that should return me back to MainViewController but I don't want to instantiate new but to use existing instance.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var story = storyboard.instantiateViewControllerWithIdentifier("MainViewController") as! ViewController
let navigationController = UINavigationController(rootViewController: story)
self.showViewController(navigationController, sender: nil)
With this code I create new so I lost data that I stored on that view.
How can I get existing instance and just move to it?
UPDATE
To explain issue better if on first view I have UISwitch and move to another ViewController and then get back to first I want to UISwitch stay same not "reset".
if you are using a navigation controller, doing this will pop to your previous controller. navigationController.popViewControllerAnimated(true)
you can use this one
self.dismissViewControllerAnimated(false, completion: nil);
Navigation controller maintains the stack of viewcontrollers. just pop your viewcontroller and you will be back to your previous view controller.
navigationController.popViewControllerAnimated(true)
or use unwind segue from storyboard.
What are Unwind segues for and how do you use them?

transitioning from one view controller to another using a button

So, I created a login page with basic logic. If username and/or password are empty, it displays an error message. If they're full, then it transitions to the next page (home). I created a second ViewController on the storyboard, and created a SecondViewController". I then defined the respective ViewController class to "SecondViewController".
On the first ViewController.swift file, i used this code:
func transition(Sender:UIButton!)
{
let secondViewController: SecondViewController = SecondViewController()
self.presentViewController(secondViewController, animated:true, completion:nil)
}
When I tested it out however, pressing the login button (when both the username and password are filled) transfers me to a black screen instead of the second View Controller. Any ideas on what to do?
If you want the view to contain things added to it on the storyboard, you could give it a Storyboard ID (a couple of boxes below where you set the class of the view controller in the storyboard).
If you give it for example the ID "secondVC" you can then create it using the following:
let secondViewController = storyboard?.instantiateViewControllerWithIdentifier("secondVC") as? SecondViewController
You can't initialize a view controller with just the default init method.
You should probably create a view controller scene in your storyboard, add a unique identifier on it, instantiate it using instantiateViewControllerWithIdentifier:, and then display it like you are doing.
You'll want to make a segue between the view controllers in your Storyboard, and call self.performSegueWithIdentifier().
Or you can give your `UIViewController an identifier and present it programmatically too:
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let secondViewController storyboard.instantiateViewControllerWithIdentifier("") as? SecondViewController
if let secondViewController = secondViewController {
self.presentViewController(secondViewController, animated:true, completion:nil)
}
There are basically three ways to do this
1)Creating segue in storyboard,though it will only work if you have single segue from that item
2)using prepareforSegue and performSegue Methods in your presenting view controller
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "YourIdentifier" {
let controller = segue.destinationViewController as!secondViewController
}
}
Then use this in your IBACtion
performSegueWithIdentifier("YourIdentifier", sender:sender)
3)(Recommended One)
let controller = self.storyboard?.instantiateViewControllerWithIdentifier("ContactsVC")! as! ContactsVC
self.presentViewController(controller, animated:true, completion:nil

Resources