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


300

問題

の新機能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でこれを達成するにはどうすればよいですか?

回答:


648

この回答は、Swift 5.2およびiOS 13.4 SDK用に最後に改訂されました。


それはすべて、新しい構文とわずかに改訂されたAPIの問題です。UIKitの基本機能は変更されていません。これは、iOS SDKフレームワークのほとんどに当てはまります。

let storyboard = UIStoryboard(name: "myStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "myVCID")
self.present(vc, animated: true)

で問題が発生した場合init(coder:)は、EridBの回答を参照してください。


3
あなたも省略できます;!;)詳しく説明していただけませんas UIViewControllerか?なぜそれが必要なのですか?
セバスチャンランバ2014年

5
asキーワードは型キャストに使用されます。これは(UIViewController *)anObject、目的c と同じです
Garoal 2014年

1
ええ、私はそれらを省略できることを知っていますが、それは長い習慣の一部です。:D instantiateViewControllerWithIdentifierリターンAnyObjectidSwiftでは同等)vcとして宣言しUIViewController、として宣言すると、に型キャストAnyObjectする必要がありUIViewControllerます。
akashivskyy 2014年

こんにちは友人、私はいくつかの異なる問題に直面しています、このコードはiOS v7.1.2を持っている私のiPad2ではなくシミュレータで実行されます。よろしければこの問題の解決を手伝ってください。
インドラ

3
@akashivskyy間違いなくあなたに。しかし、多分そうではないかもしれません。
mmc 2014

43

@akashivskyyの答えを使用してインスタンス化UIViewControllerし、例外を抱えている人々:

致命的なエラー:クラスに実装されていない初期化子 'init(coder :)'を使用しています

簡単なヒント:

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

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

詳細な説明が必要な場合は、ここで私の答えを参照してください


カスタムイニシエーターを使用する場合は、super.init(nibName:nil、bundle:nil)でsuperを呼び出すだけで、whewが正常に読み込まれるか、NIBファイルの名前で呼び出すことができます。
user1700737 2014年

4
@ user1700737 initWithNibではなくinitWithCoderを実行するストーリーボードを参照するviewControllerをインスタンス化しています。この質問を参照してくださいstackoverflow.com/questions/24036393/...
E-Riddie

こんにちは友人、私はいくつかの異なる問題に直面しています、このコードはiOS v7.1.2を持っている私のiPad2ではなくシミュレータで実行されます。よろしければこの問題の解決を手伝ってください。
インドラ

@Indraあなたはスタックで別の質問をする必要があります。リンクを教えてください。喜んでお手伝いします!
E-Riddie 2014

Swift 1.2 init(coder aDecoder: NSCoder!)では、「必須」にする必要があります。だから今、あなたは次のように記述する必要がありますrequired init(coder aDecoder: NSCoder!)
エドゥアルドViegas

18

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

迅速:

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)

}

15

アカシフスキーの答えはうまくいきます!ただし、表示されたビューコントローラから戻るときに問題が発生した場合は、この代替手段が役立ちます。それは私のために働いた!

迅速:

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

Swift 4.2更新コードは

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

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に配置すると、これでうまくいきました


7

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

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

5

よりクリーンな方法を提案したいと思います。これは、複数のストーリーボードがある場合に役立ちます

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

@nonobjcはどうですか?
StackRunner

1
@StackRunnerこれは目的cでは使用できません
XcodeNOOB

3

スウィフト4:

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

2

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

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

「アクセス可能な初期化子がないため、構築できません」というメッセージが表示されます。
PaulBénéteau2017年

ストーリーボードによって作成されたアウトレットやその他の関係は失われます
jose920405

2

スウィフト3 ストーリーボード

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

})

1

私はそれが古いスレッドであることを知っていますが、現在の解決策(特定のビューコントローラーにハードコードされた文字列識別子を使用)は非常にエラーが発生しやすいと思います。

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

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

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

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

1

スウィフト5

let vc = self.storyboard!.instantiateViewController(withIdentifier: "CVIdentifier")
self.present(vc, animated: true, completion: nil)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.