I'm presenting another view controller like this:
func goToScreen(id : String) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: id)
self.present(newViewController, animated: true, completion: nil)
}
The problem is, there is a cc. 1 second delay between the appearance of the new viewcontroller, and in the meantime the app shows an all black screen. Why is that? It looks really ugly
change status of animation to false while move to next view controller this will remove the delay. Delay happening only because of animation: true.
Use below code to solve your issue
self.present(newViewController, animated: false, completion: nil)
Hope this will help you
I was inheriting from UITabBarController instead of UIViewController from the screen I was pushing to.
I am new with iOS an in this website. I was using a navigation controller and pushViewController to switch to other views. But now I am trying to push to a view without a navigation bar. The new view should contain a Done button which once clicked should bring the user back to the last view. Do you have an idea how to achieve that? I tried this
let storyboard = UIStoryboard(name: "Main.Storyboard", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "FormViewController")
self.present(controller, animated: true, completion: nil)
I got an error
'Could not find a storyboard named 'Main.storyboard' in bundle NSBundle. I get the same error if I try FormViewController as the story board name. I set FormViewController as Storyboard ID and also as the swift file name I want to use with the interface, and Main.Storyboard is the name of the storyboard file.
You don't add the ".storyboard" part of the filename, it does that automatically:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
When dealing with the storyboard and accessing ViewController, you will have to follow these steps:
1. Assign Storyboard ID to ViewController
In your Storyboard, select the desired ViewController and assign Storyboard Id to it
2. Access the ViewController
To access the ViewController, you will need the Storyboard Id which we have set in the first step.
If you have only one storyboard you can simply do like this
let controller = self.storyboard.instantiateViewController(withIdentifier: "YourViewControllerID")
self.present(controller, animated: true, completion: nil)
**
OR
**
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "YourViewControllerID")
self.present(controller, animated: true, completion: nil)
If you are using multiple storyboards within the same project then you will have to access storyboard with it's name (without its extension i.e .Storyboard):
let storyboard = UIStoryboard(name: "YourStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "YourViewControllerID")
self.present(controller, animated: true, completion: nil)
I am working with a team and our first two views in our workflow are created programmatically. We decided afterwards that we should use storyboards to facilitate some of the UI design. The initial view controller is LoginController, then it connects to UserProfileViewController. I want to design the UI for the second view in storyboards and have it connect to UserProfileViewController. How would I do this? It works if I make the view in the storyboard the initial view. If not it does not work.
If you want to push to a Storyboard programatically here is how you do it in Swift.
//Swift 3.0
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "someViewController")
self.navigationController?.pushViewController(controller, animated: true)
The link below is another post on how to present a modal ViewController
//Swift 3.0
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "someViewController")
self.present(controller, animated: true, completion: nil)
Instantiate and Present a viewController in Swift
I'm using following code to programmatically navigate to another ViewController. It works fine, but it some how hides the navigation bar. How do I fix this? (the navigation bar is created by embeding the ViewController in the navigation controller if that matters.)
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("nextView") as NextViewController
self.presentViewController(nextViewController, animated:true, completion:nil)
Swift 5
The default modal presentation style is a card. This shows the previous view controller at the top and allows the user to swipe away the presented view controller.
To retain the old style you need to modify the view controller you will be presenting like this:
newViewController.modalPresentationStyle = .fullScreen
This is the same for both programmatically created and storyboard created controllers.
Swift 3
With a programmatically created Controller
If you want to navigate to Controller created Programmatically, then do this:
let newViewController = NewViewController()
self.navigationController?.pushViewController(newViewController, animated: true)
With a StoryBoard created Controller
If you want to navigate to Controller on StoryBoard with Identifier "newViewController", then do this:
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
self.present(newViewController, animated: true, completion: nil)
SWIFT 4.x
The Strings in double quotes always confuse me, so I think answer to this question needs some graphical presentation to clear this out.
For a banking app, I have a LoginViewController and a BalanceViewController. Each have their respective screens.
The app starts and shows the Login screen. When login is successful, app opens the Balance screen.
Here is how it looks:
The login success is handled like this:
let storyBoard: UIStoryboard = UIStoryboard(name: "Balance", bundle: nil)
let balanceViewController = storyBoard.instantiateViewController(withIdentifier: "balance") as! BalanceViewController
self.present(balanceViewController, animated: true, completion: nil)
As you can see, the storyboard ID 'balance' in small letters is what goes in the second line of the code, and this is the ID which is defined in the storyboard settings, as in the attached screenshot.
The term 'Balance' with capital 'B' is the name of the storyboard file, which is used in the first line of the code.
We know that using hard coded Strings in code is a very bad practice, but somehow in iOS development it has become a common practice, and Xcode doesn't even warn about them.
You should push the new viewcontroller by using current navigation controller, not present.
self.navigationController.pushViewController(nextViewController, animated: true)
According to #jaiswal Rajan in his answer. You can do a pushViewController like this:
let storyBoard: UIStoryboard = UIStoryboard(name: "NewBotStoryboard", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "NewViewController") as! NewViewController
self.navigationController?.pushViewController(newViewController, animated: true)
So If you present a view controller it will not show in navigation controller. It will just take complete screen. For this case you have to create another navigation controller and add your nextViewController as root for this and present this new navigationController.
Another way is to just push the view controller.
self.presentViewController(nextViewController, animated:true, completion:nil)
For more info check Apple documentation:-
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/doc/uid/TP40006926-CH3-SW96
OperationQueue.main.addOperation {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "Storyboard ID") as! NewViewController
self.present(newViewController, animated: true, completion: nil)
}
It worked for me when I put the code inside of the OperationQueue.main.addOperation, that will execute in the main thread for me.
All other answers sounds good, I would like to cover my case, where I had to make an animated LaunchScreen, then after 3 to 4 seconds of animation the next task was to move to Home screen. I tried segues, but that created problem for destination view. So at the end I accessed AppDelegates's Window property and I assigned a new NavigationController screen to it,
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let homeVC = storyboard.instantiateViewController(withIdentifier: "HomePageViewController") as! HomePageViewController
//Below's navigationController is useful if u want NavigationController in the destination View
let navigationController = UINavigationController(rootViewController: homeVC)
appDelegate.window!.rootViewController = navigationController
If incase, u don't want navigationController in the destination view then just assign as,
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let homeVC = storyboard.instantiateViewController(withIdentifier: "HomePageViewController") as! HomePageViewController
appDelegate.window!.rootViewController = homeVC
The above code works well but if you want to navigate from an NSObject class, where you can not use self.present:
let storyBoard = UIStoryboard(name:"Main", bundle: nil)
if let conVC = storyBoard.instantiateViewController(withIdentifier: "SoundViewController") as? SoundViewController,
let navController = UIApplication.shared.keyWindow?.rootViewController as? UINavigationController {
navController.pushViewController(conVC, animated: true)
}
In some cases I want my app to present a different view controller than the one that normally loads (in this case AltView rather than MainView), but I can't figure out how to do it. I tried like this:
let storyboard = UIStoryboard.init(name: "Alt", bundle: nil)
let nav = storyboard.instantiateViewControllerWithIdentifier("AltView")
let mainStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let rootVC = mainStoryboard.instantiateViewControllerWithIdentifier("MainView")
self.window!.rootViewController = rootVC
window!.makeKeyAndVisible()
self.window!.rootViewController?.presentViewController(nav, animated: true, completion: nil)
But nothing happens, the screen is just blank, no errors or warnings are being reported.
EDIT: AltView is an UINavigationController with an embedded UIViewController. The viewDidLoad() method of AltView's embedded view controller is being run, but its viewWillAppear() method is not.
What am I doing wrong?
Just set the window controller like this
let mainStoryboard = UIStoryboard.init(name: "Main", bundle: nil)
let nav = storyboard.instantiateViewControllerWithIdentifier("AltView")
self.window!.rootViewController = nav
If u want to change the controller change the window rootviewcontroller again with same code just change the identifier to the one that you want of the controller and you don't need this statement `self.window!.rootViewController?.presentViewController(nav, animated: true, completion: nil)
If you face any issues let me know