在Swift中实例化并呈现一个viewController。

时间:2021-06-05 15:01:35

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:

我开始在Xcode 6上查看新的Swift代码,并尝试了一些演示项目和教程。现在我被困在:

Instantiating and then presenting a viewController from a specific storyboard

实例化,然后从一个特定的故事板中呈现一个viewController。

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?

如何快速实现这一目标?

10 个解决方案

#1


496  

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.

如果你有init的问题(coder:),请参考EridB的答案。

#2


40  

For people using @akashivskyy's answer to instantiate UIViewController and are having the exception:

对于那些使用@akashivskyy的答案来实例化UIViewController并有例外的人:

fatal error: use of unimplemented initializer 'init(coder:)' for class

致命错误:在类中使用未实现的初始化初始化器的init(编码器:)。

Quick tip:

快速提示:

Manually implement required init?(coder aDecoder: NSCoder) at your destination UIViewController that you are trying to instantiate

手动实现所需的初始化?(coder aDecoder: NSCoder)在你的目的地UIViewController中,你正在尝试实例化。

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

If you need more description please refer to my answer here

如果你需要更多的描述,请参考我的答案。

#3


12  

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

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


10  

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!

akashivskyy的回答很好!但是,如果您从呈现的视图控制器中返回一些麻烦,这个替代方法可能会有所帮助。它为我工作!

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:

Obj-C:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"someViewController"];
[self.navigationController showViewController:vc sender:nil];

#5


6  

// "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

当我把它放到AppDelegate时,这对我来说很有用。

#6


5  

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


2  

If you have a Viewcontroller not using any storyboard/Xib, you can push to this particular VC like below call :

如果你有一个不使用任何故事板/Xib的Viewcontroller,你可以把它推到下面这个特殊的VC中:

 let vcInstance : UIViewController   = yourViewController()
 self.present(vcInstance, animated: true, completion: nil)

#8


1  

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:

例如,Main中名为vc1的视图控制器。故事板将被实例化如下:

let vc: UIViewController = R.storyboard.Main.vc1^  // where the '^' character initialize the controller

#9


1  

Swift 3 在Swift中实例化并呈现一个viewController。

斯威夫特3

let settingStoryboard : UIStoryboard = UIStoryboard(name: "SettingViewController", bundle: nil)
let settingVC = settingStoryboard.instantiateViewController(withIdentifier: "SettingViewController") as! SettingViewController
self.present(settingVC, animated: true, completion: {

})

#10


1  

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

#1


496  

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.

如果你有init的问题(coder:),请参考EridB的答案。

#2


40  

For people using @akashivskyy's answer to instantiate UIViewController and are having the exception:

对于那些使用@akashivskyy的答案来实例化UIViewController并有例外的人:

fatal error: use of unimplemented initializer 'init(coder:)' for class

致命错误:在类中使用未实现的初始化初始化器的init(编码器:)。

Quick tip:

快速提示:

Manually implement required init?(coder aDecoder: NSCoder) at your destination UIViewController that you are trying to instantiate

手动实现所需的初始化?(coder aDecoder: NSCoder)在你的目的地UIViewController中,你正在尝试实例化。

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

If you need more description please refer to my answer here

如果你需要更多的描述,请参考我的答案。

#3


12  

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

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


10  

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!

akashivskyy的回答很好!但是,如果您从呈现的视图控制器中返回一些麻烦,这个替代方法可能会有所帮助。它为我工作!

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:

Obj-C:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"someViewController"];
[self.navigationController showViewController:vc sender:nil];

#5


6  

// "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

当我把它放到AppDelegate时,这对我来说很有用。

#6


5  

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


2  

If you have a Viewcontroller not using any storyboard/Xib, you can push to this particular VC like below call :

如果你有一个不使用任何故事板/Xib的Viewcontroller,你可以把它推到下面这个特殊的VC中:

 let vcInstance : UIViewController   = yourViewController()
 self.present(vcInstance, animated: true, completion: nil)

#8


1  

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:

例如,Main中名为vc1的视图控制器。故事板将被实例化如下:

let vc: UIViewController = R.storyboard.Main.vc1^  // where the '^' character initialize the controller

#9


1  

Swift 3 在Swift中实例化并呈现一个viewController。

斯威夫特3

let settingStoryboard : UIStoryboard = UIStoryboard(name: "SettingViewController", bundle: nil)
let settingVC = settingStoryboard.instantiateViewController(withIdentifier: "SettingViewController") as! SettingViewController
self.present(settingVC, animated: true, completion: {

})

#10


1  

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