I started taking a look of the new Swift
on Xcode 6
, and I tried some demo projects and tutorials. Now I am stuck at:
Instantiating and then presenting a viewController
from a specific storyboard
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"myStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"myVCID"];
[self presentViewController:vc animated:YES completion:nil];
How to achieve this on Swift?
This question is related to
ios
objective-c
swift
uiviewcontroller
guard let vc = storyboard?.instantiateViewController(withIdentifier: "add") else { return }
vc.modalPresentationStyle = .fullScreen
present(vc, animated: true, completion: nil)
Swift 5
let vc = self.storyboard!.instantiateViewController(withIdentifier: "CVIdentifier")
self.present(vc, animated: true, completion: nil)
For people using @akashivskyy's answer to instantiate UIViewController
and are having the exception:
fatal error: use of unimplemented initializer 'init(coder:)' for class
Quick tip:
Manually implement required init?(coder aDecoder: NSCoder)
at your destination UIViewController
that you are trying to instantiate
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
If you need more description please refer to my answer here
No matter what I tried, it just wouldn't work for me - no errors, but no new view controller on my screen either. Don't know why, but wrapping it in timeout function finally made it work:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.0) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "TabletViewController")
self.present(controller, animated: true, completion: nil)
}
Swift 3
let settingStoryboard : UIStoryboard = UIStoryboard(name: "SettingViewController", bundle: nil)
let settingVC = settingStoryboard.instantiateViewController(withIdentifier: "SettingViewController") as! SettingViewController
self.present(settingVC, animated: true, completion: {
})
This link has both the implementations:
Swift:
let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
self.presentViewController(viewController, animated: false, completion: nil)
Objective C
UIViewController *viewController = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:@"ViewController"];
This link has code for initiating viewcontroller in the same storyboard
/*
Helper to Switch the View based on StoryBoard
@param StoryBoard ID as String
*/
func switchToViewController(identifier: String) {
let viewController = self.storyboard?.instantiateViewControllerWithIdentifier(identifier) as! UIViewController
self.navigationController?.setViewControllers([viewController], animated: false)
}
I created a library that will handle this much more easier with better syntax:
https://github.com/Jasperav/Storyboardable
Just change Storyboard.swift and let the ViewControllers
conform to Storyboardable
.
If you have a Viewcontroller not using any storyboard/Xib, you can push to this particular VC like below call :
let vcInstance : UIViewController = yourViewController()
self.present(vcInstance, animated: true, completion: nil)
If you want to present it modally, you should have something like bellow:
let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewControllerID")
self.showDetailViewController(vc as! YourViewControllerClassName, sender: self)
Swift 4.2 updated code is
let storyboard = UIStoryboard(name: "StoryboardNameHere", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "ViewControllerNameHere")
self.present(controller, animated: true, completion: nil)
I know it's an old thread, but I think the current solution (using hardcoded string identifier for given view controller) is very prone to errors.
I've created a build time script (which you can access here), which will create a compiler safe way for accessing and instantiating view controllers from all storyboard within the given project.
For example, view controller named vc1 in Main.storyboard will be instantiated like so:
let vc: UIViewController = R.storyboard.Main.vc1^ // where the '^' character initialize the controller
akashivskyy's answer works just fine! But, in case you have some trouble returning from the presented view controller, this alternative can be helpful. It worked for me!
Swift:
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController
// Alternative way to present the new view controller
self.navigationController?.showViewController(vc, sender: nil)
Obj-C:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"someViewController"];
[self.navigationController showViewController:vc sender:nil];
Swift 4:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC
I would like to suggest a much cleaner way. This will be useful when we have multiple storyboards
1.Create a structure with all your storyboards
struct Storyboard {
static let main = "Main"
static let login = "login"
static let profile = "profile"
static let home = "home"
}
2. Create a UIStoryboard extension like this
extension UIStoryboard {
@nonobjc class var main: UIStoryboard {
return UIStoryboard(name: Storyboard.main, bundle: nil)
}
@nonobjc class var journey: UIStoryboard {
return UIStoryboard(name: Storyboard.login, bundle: nil)
}
@nonobjc class var quiz: UIStoryboard {
return UIStoryboard(name: Storyboard.profile, bundle: nil)
}
@nonobjc class var home: UIStoryboard {
return UIStoryboard(name: Storyboard.home, bundle: nil)
}
}
Give the storyboard identifier as the class name, and use the below code to instantiate
let loginVc = UIStoryboard.login.instantiateViewController(withIdentifier: "\(LoginViewController.self)") as! LoginViewController
// "Main" is name of .storybord file "
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
// "MiniGameView" is the ID given to the ViewController in the interfacebuilder
// MiniGameViewController is the CLASS name of the ViewController.swift file acosiated to the ViewController
var setViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MiniGameView") as MiniGameViewController
var rootViewController = self.window!.rootViewController
rootViewController?.presentViewController(setViewController, animated: false, completion: nil)
This worked fine for me when i put it in AppDelegate
Source: Stackoverflow.com