在Swift中实例化和呈现viewController

时间:2014-06-04 11:16:57

标签: ios objective-c swift uiviewcontroller

问题

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

从特定故事板中实例化然后呈现viewController

Objective-C解决方案

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"myStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"myVCID"];
[self presentViewController:vc animated:YES completion:nil];

如何在Swift上实现这一目标?

15 个答案:

答案 0 :(得分:590)

这一切都是新语法的问题,功能没有改变:

// Swift 3.0

let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "someViewController")
self.present(controller, animated: true, completion: nil)

如果您遇到init(coder:)问题,请参阅EridB's answer

答案 1 :(得分:43)

对于使用@akashivskyy's answer实例化UIViewController且有异常的人:

  

致命错误:使用未实现的初始化程序'init(coder :)'用于类

快速提示:

在您尝试实例化的目的地required init?(coder aDecoder: NSCoder)上手动实施UIViewController

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

如果您需要更多说明,请参阅我的回答here

答案 2 :(得分:18)

This link has both the implementations:

夫特:

let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
self.presentViewController(viewController, animated: false, completion: nil)

目标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)

}

答案 3 :(得分:13)

akashivskyy的回答很好!但是,如果您从显示的视图控制器返回时遇到一些问题,则此替代方法可能会有所帮助。它对我有用!

夫特:

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];

答案 4 :(得分:7)

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

当我把它放在AppDelegate

中时,这对我来说很好

答案 5 :(得分:7)

如果你想以模态方式呈现它,你应该有类似下面的东西:

let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewControllerID")
self.showDetailViewController(vc as! YourViewControllerClassName, sender: self)

答案 6 :(得分:7)

Swift 4.2更新的代码是

let storyboard = UIStoryboard(name: "StoryboardNameHere", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "ViewControllerNameHere")
self.present(controller, animated: true, completion: nil)

答案 7 :(得分:3)

斯威夫特4:

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC

答案 8 :(得分:2)

如果您的Viewcontroller没有使用任何storyboard / Xib,您可以像下面的电话一样推送到这个特定的VC:

#setup.cfg contents:

[nosetests]
exe = True
tests = workflow/, other/dir/full/of/tests/, direct/file/my_test.py

答案 9 :(得分:2)

我想提出一种更简洁的方法。当我们有多个故事板时,这将很有用

1。使用所有情节提要创建一个结构

tbl_books

2。像这样创建一个UIStoryboard扩展

struct Storyboard {
      static let main = "Main"
      static let login = "login"
      static let profile = "profile" 
      static let home = "home"
    }

使用情节提要标识符作为类名,并使用以下代码实例化

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

答案 10 :(得分:1)

我知道它是一个旧线程,但我认为当前的解决方案(使用给定视图控制器的硬编码字符串标识符)很容易出错。

我已经创建了一个构建时脚本(你can access here),这将创建一个编译器安全的方法来访问和实例化给定项目中所有storyboard的视图控制器。

例如, Main.storyboard 中名为 vc1 的视图控制器将实例化为:

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

答案 11 :(得分:1)

斯威夫特3 Storyboard

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

})

答案 12 :(得分:1)

无论我尝试什么,它都不适合我 - 没有错误,但我的屏幕上也没有新的视图控制器。不知道为什么,但将它包装在超时功能中最终使其工作:

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 :(得分:0)

我创建了一个库,它将以更好的语法更轻松地处理此问题:

https://github.com/Jasperav/Storyboardable

只需更改Storyboard.swift并让ViewControllers符合Storyboardable

答案 14 :(得分:0)

guard let vc = storyboard?.instantiateViewController(withIdentifier: "add") else { return }
        vc.modalPresentationStyle = .fullScreen
        present(vc, animated: true, completion: nil)