web-dev-qa-db-ja.com

SwiftでviewControllerをインスタンス化して表示する

問題

私はXcode 6の新しいSwiftを見始めました、そして私はいくつかのデモプロジェクトとチュートリアルを試しました。今私は立ち往生しています:

特定のストーリーボードからviewControllerをインスタンス化して提示する

Objective-Cソリューション

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

Swiftでこれを実現する方法

274
E-Riddie

すべてが新しい構文の問題であり、機能は変更されていません。

// 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の回答 を参照してください。

587
akashivskyy

@ akashivskyy's answer を使用してUIViewControllerをインスタンス化し、例外がある人々のために:

致命的エラー:クラスに未実装の初期化子 'init(coder :)'を使用しました

クイックヒント:

インスタンス化しようとしている宛先UIViewControllerに手動でrequired init?(coder aDecoder: NSCoder)を実装する

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

もっと説明が必要な場合は私の答えを参照してください ここ

43
E-Riddie

このリンクは両方の実装があります:

迅速:

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

このリンクは、同じストーリーボードでビューコントローラを起動するためのコードを持っています

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

}
18
Abhijeet

akashivskyyの回答は問題ありません。しかし、表示されているView Controllerから戻るのに問題がある場合は、この方法が役立ちます。それは私のために働いた!

迅速:

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];
12
Nahuel Roldan
// "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に入れたときこれは私のためにうまく働いた

7
Maxxafari

モーダルに提示したい場合は、以下のようなものが必要です。

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

Swift 4.2の更新されたコードは

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

スイフト4:

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

ストーリーボードやXibを使用していないViewControllerがある場合は、以下のようにこの特定のVCにプッシュできます。

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

もっときれいな方法を提案したいと思います。これは複数の絵コンテがある場合に便利です。

1.ストーリーボードをすべて使用して構造を作成する

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

2.このようなUIStoryboard拡張を作成します

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
2
vijeesh

スイフト3 Storyboard

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

})
1
Giang

何を試しても、それだけではうまくいきませんでした - エラーもなく、画面に新しいView Controllerもありません。理由はわかりませんが、タイムアウト機能でラップすることでようやく動作しました。

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
Starwave

私はそれが古いスレッドであることを知っています、しかし私は現在の解決策(与えられたView Controllerのためにハードコードされた文字列識別子を使う)は非常にエラーを起こしやすいと思います。

私はビルドタイムスクリプトを作成しました(これで ここからアクセスできます )これは、プロジェクト内のすべてのストーリーボードからView Controllerにアクセスしてインスタンス化するためのコンパイラ安全な方法を作成します。

たとえば、 vc1 in Main.storyboard という名前のビューコントローラは、次のようにインスタンス化されます。

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

私はより良い構文でこれをはるかに簡単に処理するライブラリを作成しました:

https://github.com/Jasperav/ストーリーボード可能

Storyboard.Swiftを変更して、ViewControllersStoryboardableに準拠させるだけです。

0
J. Doe