I am learning ios development and am trying to make an app that has two views, each with a button that when pressed will send you to the other view. I have the two scenes set up in the storyboard and the button connected to an action. According to what I've read, using the instantiateViewController and an identifier should be enough to change the view. But when I run the simulator the first view appears but clicking the button has no effect. I dont't even get a error message.
#IBAction func SwitchViews(_ sender: UIButton) {
//Switch view controllers
let vc = storyboard?.instantiateViewController(withIdentifier: "second")
navigationController?.pushViewController(vc!, animated: true)
}
Have you embed you storyboard to navigation controller.In your code navigation controller optional so controller is not able get navigation controller.
you have to embed your first storyboard to navigation controller And it will work.You can do it by In Xcode>Editor>Embed In>Navigation Controller.
Just one suggestion if you are going to be developing apps that doesn't use navigation view what you have done is slightly off. The right way to do the connection to multiple views in a single view application is like this. I'll explain it in steps
Step 1 - Add a ViewController to your story board
Step 2 - Create a cocoa touch class from file - new - file (command + N will also do the trick)
!!! make sure its cocoa touch class !!!
Step 3 - keep subclass of as UIViewController enter the class name keep it unique to what the view does so the code looks clean and clear for everyone.
Step 4 - Hit next and finish. Now go to the story board and add the class name to the view controller you have created inside the identity inspector and add the storyboard identifier name as well
Step 5 - link your button to an action within your swift file as TouchUpInside and add the following code
#IBAction func startButtonPressed(_ sender: UIButton) {
let controllerVariable = self.storyboard?.instantiateViewController(withIdentifier: "storyboardIdentifier") as! ViewControllerClassName
self.present(controllerVariable, animated: true, completion: nil)
}
This should do the trick for creating single view applications and then building up your app with multiple screens.
But if your app uses IOS default navigation controller style like a nav bar with navigation items and a back button best practice is to use the nav controller.
If it doesn't then you have complete control over how you design your user interface by following the above steps.
Hope this helps :)
Related
I am practicing IOS app using swift.
I have created three view controllers Default, Login view, and Register Page.
1)Default view is embedded with a Navigation controller.
2)Default view is connected through a segue(Present Modally)
3)In Login view, SignUp button is connected through a segue(present Modally) to Register view.
Expected: I should see default view and then Login view should load.
Problem: I can see only default view. But I am unable to see Login view.
Attached screenshot is my UI. Please zoom for better view.
Hope any one will help me. Thank you in advance.
Your Storyboard seems to be fine.
There are two different ways to perform a wind segue:
Direct segue
1.1 Just drop an UIButton into your first View Controller.
1.2 Then pressing Ctrl, select the button and drag it into the second View Controller (Login View Controller). A blue arrow will appear, drag and drop it into the next view controller.
1.3 Done! You can run your app and click on the added button, it will send you to the next view controller.
Programmatically segue:
2.1 For each one of your segues you need to provide an identifier. For this, you need to go to your storyboard, select each segue and give a name on the inspector.
2.2 Create a ViewController Cocoa Touch Class file for each View Controller in your Storyboard ( File > New > File... > Cocoa Touch Class).
2.3 Once done, it will show you the recently ViewController file instead of the storyboard. Go again to your Storyboard Select the second View Controller (lets call it OtherViewController), and then go to the “Identity Inspector” in the Utility Pane. It’s the icon that looks like a card with a picture in the top left corner and some writing everywhere else (it’s selected in blue in the screenshot below). In there, set the “Class” part of the “Custom Class” section to our new OtherViewController. If it is a compatible subclass (in this case of UIViewController), it will accept it. It will also probably autocomplete once you start typing a compatible class.
2.4 Next, you need to generate an action to perform the segue and go from one View Controller to another. Additionally, you can send a value to the next view controller (eg. numberToDisplay). For this you will need to add this code:
Code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "SegueCustomIdentifier"
{
if let destinationVC = segue.destinationViewController as? OtherViewController {
destinationVC.numberToDisplay = counter
}
}
}
2.5 To perform this segue, you will need to add the next code into your first View Controller and attach it to a simple action, for example: a button pressed event.
self.performSegueWithIdentifier("HAIDetails", sender: self)
For more details please visit: tutorial
I ran into an issue where I had the following setup, but was unable to get an unwind segue to work.
The storyboards were created several months ago, and were refactored from an original main storyboard to split them out into individual ones, with each storyboard having a single view controller.
The storyboards:
MainMenu.storyboard (Contains the navigation controller)
SubMenu.storyboard (Contains the segue that sends the user to the destination storyboard)
Destination.storyboard (Should contain unwind segue)
In the SubMenu viewcontroller, I have the following unwind segue:
#IBAction func unwindToSubMenu(segue: UIStoryboardSegue) {}
I then place a bar button item on the navigation item for the destination view controller. Attempting to link the bar button item to the exit icon on the Destination.storyboard file does not result in the unwindToSubMenu segue appearing.
Also, right clicking on the exit icon results in an empty field.
I did attempt to move the Destination.storyboard contents back to the SubMenu.storyboard to see if it had something to do with the reference links, but this was unsuccessful.
Updated with a better answer.
I ran into this problem again using the latest version of XCode (8.2.1) where a properly configured segue was not appearing.
To make sure I was not insane, I first created a small sample project where I only lifted the relevant code, and was able to confirm that it was set up properly.
With that out of the way, I found a better solution to this issue by creating a garbage storyboard & associated view controller.
The view controller only contained this code:
class GarbageViewController: UIViewController {
#IBAction func unwind(_ segue: UIStoryboardSegue) { }
}
This was then set as the view controller for the garbage storyboard.
I then clicked on the exit outlet in the garbage storyboard file to confirm that the unwind method defined above appeared. Once it appeared, the unwind segue I wanted suddenly became available as well.
I am a beginner programmer and have been trying to teach myself to program a basic app online. I am currently trying to make Tetris on iOS using Swift 2 and Xcode 7. However, I am having trouble changing views. I began with the iOS Game template and have a view named GameViewController which my game runs inside. When the user loses, I want to switch from that view to one called EndGameView, which I have created in the storyboard and linked to the class EndGameView. My issue is that I do not know how to present the EndGameView programmatically without using, for example, a button added in using the storyboard and then control-dragging to the EndGameView.
let endGameView = EndGameView()
super.presentViewController(endGameView, animated: true, completion: nil)
Please excuse my stupidity as I'm sure I'm making a dumb error and thanks for any help.
A simple way to change view controller is to create a segue between your two view controllers and call it when the player dies, basically going from your game view controller to your EndGameViewController. Here is a line of code to call a segue: self.performSegueWithIdentifier("SEAGUEIDTOLOGGEDINSCREEN", sender: nil)
Replace SEAGUEIDTOLOGGEDINSCREEN with the segue you have created's id.
How to create a segue: Right click and drag from your GameViewController to your EndGameViewController and select "Show"
After inking them, you should see a link, click on it and you should see on your side the id and name.
Add the name of the segue to the identifier slot, and use that on calling it.
I am using a UISplitViewController to implement a Master/Detail flow app.
I am not using a Navigation Controller.
To go from the MasterViewController to the DetailViewController I am using:
performSegueWithIdentifier("showDetail", sender: self)
What should I use to go back from the DetailViewController to the MasterViewController?
I found a simple solution using the unwind action.
In the MasterControllerView I add the code:
#IBAction func backFromDetail(segue: UIStoryboardSegue) {
print("back")
}
Using InterfaceBuilder, I create a custom Back button inside the DetailViewController, and I connect it to the Exit icon (as explained here) selecting "backFromDetail".
After this, everything works magically! You just click on the custom Back button to go back to master.
I have a problem again. I work with storyboard in Xcode 6 with Swift as programming language. Before I want to present a view (with a view controller) on starting my app I want to test the internet connection and my server connection. If both connections are available I want to present a view1 and if not I want to present a view2. But I don't want to show a view with a spinner while checking the connection. So I thought I can manage it over the AppDelegate class. In the function func application() I want to decide which view (view1 or view2) is loaded at first. But for this solution I have to instantiate two view controllers that are connected to my two views in storyboard. I don't know if it is possible.
So my question, is it possible to instantiate these two specific storyboard view controllers in my AppDelegate class? And if it is possible, how can I do this by code?
If it is not possible, how can I solve my problem? At the moment I always show a view controller with a spinner (view0) and if connection is available I go to view1 and if connection is not available I go to view2 from my view0 controller like this:
override func viewDidAppear(animated: Bool) {
//some code
self.presentViewController(view1, animated: true, completion: nil)
//some other code
}
You can load a specific view controller from a storyboard with this call:
let viewController = self.window?.rootViewController?.storyboard?.instantiateViewControllerWithIdentifier("SomethingViewController") as UIViewController
self.window?.rootViewController = viewController
But to be honest, it doesn't seem good to make the user wait with no information while you do the connection tests.
It would be better to show a temporary view controller during the waiting, unless those tests are really fast :)
Edit: corrected the code.
It's a hackish solution, as it will load a new rootViewController after initializing the original one I suppose. But it should work.
A more correct alternative would be creating the project as "empty application" and loading the storyboard by code, directly in the controller you want.