首页 文章

在Swift中实例化和呈现viewController

提问于
浏览
255

问题

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

Instantiating and then presenting a viewController from a specific storyboard

Objective-C解决方案

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

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

14 回答

  • 2

    斯威夫特4:

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

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

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

  • 14

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

    致命错误:在课堂上使用未实现的初始化程序'init(coder :)'

    Quick tip:

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

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

    如果您需要更多描述请参考我的回答here

  • 1

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

    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];
    
  • 1
    // "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中时,这对我来说很好

  • 41

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

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

    如果你有一个不使用任何storyboard / Xib的Viewcontroller,你可以像下面这样调用这个特定的VC:

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

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

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

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

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

    斯威夫特3
    Storyboard

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

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

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

    我想建议一个更清洁的方式 . 当我们有多个故事板时,这将非常有用

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

    将故事板标识符作为类名称,并使用以下代码进行实例化

    let loginVc = UIStoryboard.login.instantiateViewController(withIdentifier: "\(LoginViewController.self)") as! LoginViewController
    
  • 1

    我创建了一个库,可以通过更好的语法更轻松地处理这个问题:

    https://github.com/Jasperav/Storyboardable

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

  • 0

    Swift 4.2更新了代码

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

相关问题