可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Issue
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
Objective-C Solution
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?
回答1:
It all is a matter of the new syntax, functionality hasn\'t changed:
// Swift 3.0
let storyboard = UIStoryboard(name: \"MyStoryboardName\", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: \"someViewController\")
self.present(controller, animated: true, completion: nil)
If you\'re having problems with init(coder:)
, please refer to EridB\'s answer.
回答2:
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
回答3:
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)
}
回答4:
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];
回答5:
// \"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
回答6:
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)
回答7:
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)
回答8:
Swift 4:
let storyboard = UIStoryboard(name: \"Main\", bundle: nil)
let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: \"YourVC\") as! YourVC
回答9:
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
回答10:
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
回答11:
Swift 3
let settingStoryboard : UIStoryboard = UIStoryboard(name: \"SettingViewController\", bundle: nil)
let settingVC = settingStoryboard.instantiateViewController(withIdentifier: \"SettingViewController\") as! SettingViewController
self.present(settingVC, animated: true, completion: {
})
回答12:
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)
}
回答13:
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
.
回答14:
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)