Swift 3 View controller has no segue with identifier - ios

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.

Related

How to change UIPageViewController VCs by UIButton Swift 4.0?

I have UIPageViewController with 3 UIViewControllers ("FirstVC", "SecondVC", "ThirdVC").
ViewControllers changes by scroll, but I need to change its by click on UIButtons.
How I can do this?
Maybe some func, in which VC will setup by StoryboardID?
Thanks for all answers!
You can easily programmatically navigate through the pages of a UIPageViewController using:
setViewControllers([targetPage], direction: .forward, animated: true, completion: nil)
In the case where you have a UIPageViewController embedded in a ContainerView, and you want buttons in the "root" view to control the page view controller, the basic process is:
add navigation methods (funcs) to your page view controller class
save a reference to the page view controller when it is loaded have
your buttons call the navigation funcs using that reference
When your "root" view controllers loads and instantiates the view controller that is embedded in your ContainerView, it calls prepare(for segue:...) - which is where you get your reference.
In Storyboard, where you embed your view controller in the ContainerView, you will see a standard "segue" connection. In the Attributes Inspector, give that segue an Identifier, such as "PageControllerEmbedSegue".
In your root controller class, add a class-level var:
var myPageVC: BasicPageViewController?
and in prepare():
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// get a reference to the embedded PageViewController on load
if let vc = segue.destination as? BasicPageViewController,
segue.identifier == "PageControllerEmbedSegue" {
self.myPageVC = vc
}
}
Now, you can call functions / get properties of your embedded view controller.
I have a full example on GitHub: https://github.com/DonMag/EmbeddedPageView
There are a couple ways. You could add a segue in the Storyboard file and call
performSegue(withIdentifier: "toResponseTime", sender: self)
otherwise you could do something like.
let controller = self.storyboard!.instantiateViewController(withIdentifier: "AngelDetailViewController") as! AngelDetailViewController
self.navigationController!.pushViewController(controller, animated: true)

3 ways of view controller transition

i am a beginner in iOS development, and recently, i just follow along the tutorial for beginners.
let say i want to move from one VC to another VC by clicking a button, so i just find out that there are three ways to move from one ViewController to another ViewController (modal segue).
in main storyboard, i just click control and drag from the button to th destination view controller and choose present modally
programmaticaly, by implementing the code below
#IBAction func logInButtonDidPressed(_ sender: Any) {
// modal transition to VC2
let viewController2 =
storyboard?.instantiateViewController(withIdentifier:
"ViewController2") as! ViewController2
present(viewController2, animated: true, completion: nil)
}
programatically,by using perform segue function
#IBAction func logInButtonDidPressed(_ sender: Any) {
performSegue(withIdentifier: "toSecondViewController", sender: self)
}
are they just the same ? or is it used for different cases?
Thanks in advance :)
Yes, they are similar. And the obvious difference I think is the data passing. The first and third one are same, use the following method to pass data to next controller:
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
if let viewController2 = segue.destination as? ViewController2 {
viewController2.someProperty = someValue
}
}
For second transition, you directly set the data when creating the next controller:
let viewController2 = storyboard?.instantiateViewController(withIdentifier:
"ViewController2") as! ViewController2
viewController2.someProperty = someValue
present(viewController2, animated: true, completion: nil)
I would use segues, as there are some advantages compared to manual presentation:
You can create unwind segues to exit the current view controller to any view controller in the hierarchy.
You can add 3D touch support to segues with one mouse click.
The first and last method produce identical results. I would create segues with clicking and dragging whenever possible. If you need to do some data validation or other stuff before performing a transition, you have to call the performSegue method manually.

prepareForSegue into view controller with a container view

I have a storyboard with two main view controllers (ViewController / SecondViewController) and a container with an embedSegue that displays the EmbeddedViewController view.
Desired Result
I would like to pass the 5 from ViewController to EmbeddedViewController using prepareForSegue (I don't see a need for delegation here, since the data is only going 1 way, and that's TO the EmbeddedViewController.) Once "Segue" button is pressed, the second view controller appears with the yellow VC embedded with 5 in it.
Note - SecondViewController has no user interaction in displaying EmbeddedViewController. It just shows up automatically.
Problem
I can't get a reference to EmbeddedViewController from the mainSegue prepareForSegue. Nor can I access any child View Controllers from SecondViewController. Thought I could access properties of EmbeddedViewController if I access the children VC's of SecondViewController. See code below.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "mainSegue" {
let secondVCSegue = segue.destinationViewController as! SecondViewController
print("array -- \(secondVCSegue.childViewControllers)")
// Array prints nothing. Just a blank [] :(
}
}
Any tips are appreciated thanks.

performSegueWithIdentifier doesn't work in a different ViewController

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).

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.)

Resources