クラスからプログラムでストーリーボードを読み込むにはどうすればよいですか?


183

私の問題は、ストーリーボードxibの両方を使用する方法を探していたことです。しかし、プログラムでストーリーボードを読み込んで表示する適切な方法が見つかりません。プロジェクトはxibを使用して開発を開始しましたが、現在、すべてのxibファイルをストーリーボードにネストすることは非常に困難です。それでalloc, init, push、viewControllersのように、コードでそれを行う方法を探していました。私の場合、ストーリーボードにコントローラーが1つだけUITableViewControllerあります。これには、表示するコンテンツを含む静的セルがあります。大規模なリファクタリングを行わずにxibとストーリーボードの両方を使用する適切な方法を知っている人がいれば、私はどんな助けにも感謝します。

回答:


370

ストーリーボードで属性インスペクターに移動し、ビューコントローラーの識別子を設定します。その後、次のコードを使用してそのビューコントローラーを提示できます。

UIStoryboard *sb = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:@"myViewController"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];

65
[sb instantiateInitialViewController]シーンのデフォルトのビューコントローラから開始する場合に便利です。
描いた2012年

ジェームス、ありがとう!Storyboardのビューをインスタンス化する方法を理解するためにかなりの時間を探してきました。あなたの答え(そしてkokokoの質問)は最も新鮮です。
bejonbee 2012

James Beithのコードでは、現在のビューコントローラーでUIViewControler * vcを切り替える場合は、そのUIViewControler * vcを再利用する必要があります。ユーザーが新しいビューのボタンを押すまで、VCがストーリーボードのペン先に固定されて配線されるという難しい方法を見つけました。このコードの以前の呪文から破棄されたVCでメモリリークが発生しています。
SWoo 2014

11
アプリのデリゲートでこれを行う方法を知りたい場合は、[self presentViewcontroller]ロジックを次の順序でこれらの行に置き換えます:1)self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];2)self.window.rootViewController = vc;および3)[self.window makeKeyAndVisible];。またmodalTransitionStyle、これはアプリデリゲートからのモーダル遷移ではないため、おそらく線を取り除くことができます。
lewiguez 14

参考までに、モーダルポップアップではなく新しいストーリーボードを「プッシュ」する場合は、chaithraVeereshの答えを見てください。
アダムジョンズ

76

スウィフト3

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "viewController")
self.navigationController!.pushViewController(vc, animated: true)

スウィフト2

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController")
self.navigationController!.pushViewController(vc, animated: true)

前提条件

ストーリーボードIDをビューコントローラーに割り当てます。

ストーリーボードID

IB> IDインスペクターの表示> ID>ストーリーボードID

Swift(レガシー)

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController") as? UIViewController
self.navigationController!.pushViewController(vc!, animated: true)

編集:フレッドAのコメントで提案されたSwift 2

navigationControllerなしで使用したい場合は、次のように使用する必要があります。

    let Storyboard  = UIStoryboard(name: "Main", bundle: nil)
    let vc = Storyboard.instantiateViewController(withIdentifier: "viewController")
    present(vc , animated: true , completion: nil)

1
スウィフト2では、あなたが「?としてのUIViewController」を追加する必要はありません、コンパイラが自動的に決定
フレデリック・ダッダ

2
またはself.storyboard、line1&2を実行してマージすることができます
Honey

17

属性インスペクターでそのビューコントローラーの識別子を指定すると、以下のコードが私のために機能します

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
DetailViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:@"DetailViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];

5

これを試して

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:@"Login"];

[[UIApplication sharedApplication].keyWindow setRootViewController:vc];

他の回答に示すように、あなたはUINavigationControllerを使用していない場合は、これを使用してください
latenitecoder

2

迅速な
NavigationControllerpushControllerで置き換えることができます

present(vc, animated:true , completion: nil)

1

以下のために迅速な3と4、あなたはこれを行うことができます。StoryboardIDと等しいStoryboardの名前を設定することをお勧めします。

enum StoryBoardName{
   case second = "SecondViewController"
}
extension UIStoryBoard{
   class func load(_ storyboard: StoryBoardName) -> UIViewController{
      return UIStoryboard(name: storyboard.rawValue, bundle: nil).instantiateViewController(withIdentifier: storyboard.rawValue)
   }
}

次に、次のようにストーリーボードをViewControllerにロードできます。

class MyViewController: UIViewController{
     override func viewDidLoad() {
        super.viewDidLoad()
        guard let vc = UIStoryboard.load(.second) as? SecondViewController else {return}
        self.present(vc, animated: true, completion: nil)
     }

}

新しいStoryboardを作成するときは、StoryboardIDに同じ名前を設定し、enum " StoryBoardName "にStoryboard nameを追加します。


0

いつでもルートコントローラに直接ジャンプできます。

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateInitialViewController];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];

0

以下の拡張機能を使用すると、Storyboardとそれを関連付けることができますUIViewController。例:あなたが持っている場合UIViewControllerという名前ModalAlertViewControllerと「ModalAlert」などという名前のストーリーボード

let vc: ModalAlertViewController = UIViewController.loadStoryboard("ModalAlert")

両方のロードされますStoryboardUIViewControllerしてvc型になりますModalAlertViewControllerストーリーボードのストーリーボードIDがストーリーボードと同じ名前であり、ストーリーボードがIs Initial View Controllerとしてマークされていると仮定します

extension UIViewController {
    /// Loads a `UIViewController` of type `T` with storyboard. Assumes that the storyboards Storyboard ID has the same name as the storyboard and that the storyboard has been marked as Is Initial View Controller.
    /// - Parameter storyboardName: Name of the storyboard without .xib/nib suffix.
    static func loadStoryboard<T: UIViewController>(_ storyboardName: String) -> T? {
        let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
        if let vc = storyboard.instantiateViewController(withIdentifier: storyboardName) as? T {
            vc.loadViewIfNeeded() // ensures vc.view is loaded before returning
            return vc
        }
        return nil
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.