web-dev-qa-db-ja.com

ストーリーボードからのView Controllerのインスタンス化と新しいインスタンスの作成

ストーリーボードからView Controllerをインスタンス化することと、その新しいインスタンスを作成することの機能的な違いは何ですか?例えば:

#import "SomeViewController.h"

...

SomeViewController *someViewController = [SomeViewController new];

versus

#import "SomeViewController.h"

...

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];

SomeViewController *someViewController = [storyboard instantiateViewControllerWithIdentifier:@"SomeViewController"];

どちらの場合でも、someViewControllerは事実上同じものですか?

39
Benjamin Martin

主な違いは、UIViewControllerのサブビューがインスタンス化される方法です。

2番目のケースでは、ストーリーボードで作成したすべてのビューが自動的にインスタンス化され、ストーリーボードで指定したとおりにすべてのアウトレットとアクションがセットアップされます。

最初のケースでは、それは起こりません。生のオブジェクトを取得するだけです。すべてのサブビューを割り当ててインスタンス化し、制約などを使用してレイアウトし、すべてのアウトレットとアクションを自分で接続する必要があります。 Apple推奨loadViewUIViewControllerメソッドをオーバーライドしてこれを実行します。

32
dpassage

2番目のケースでは、View Controllerがストーリーボードからビューをロードし、満足します。

最初のケースでは、そうではありません。他の手順(loadViewまたはviewDidLoadのオーバーライド、またはSomeViewController.xibという名前のxibの作成など)を行っていない限り、空の白いビューが表示され、悲しくなります。

13
rob mayoff

Swiftで同じことができます、

var someVC = self.storyboard?.instantiateViewControllerWithIdentifier("SomeViewController") as! SomeViewController

ストーリーボードのIdentifierをSomeViewControllerに指定し、チェックマークをストーリーボードIDを使用にチェックする必要があります。

3
Joseph

同じものではありません。ストーリーボードには、おそらくいくつかのUI要素がレイアウトされています。ストーリーボードを使用して、制約とプロパティを設定できます。ストーリーボードを介してViewControllerをインスタンス化すると、それらのサブビューがどこにあり、そのプロパティが何であるかについてのすべての指示が得られます。単に[SomeViewController new]ストーリーボードがView Controllerに対して持っているすべての指示を取得していない。

素敵なテストは、UIViewControllerをストーリーボードに追加し、その上に赤いビューをドラッグすることです。両方の方法を使用してインスタンス化し、違いを確認します。

3
Kris Gellci
simple Swift 3 extension   
 fileprivate enum Storyboard : String {
        case main = "Main"
    }

    fileprivate extension UIStoryboard {
        static func loadFromMain(_ identifier: String) -> UIViewController {
            return load(from: .main, identifier: identifier)
        }

        static func load(from storyboard: Storyboard, identifier: String) -> UIViewController {
            let uiStoryboard = UIStoryboard(name: storyboard.rawValue, bundle: nil)
            return uiStoryboard.instantiateViewController(withIdentifier: identifier)
        }
    }

    // MARK: App View Controllers

    extension UIStoryboard {
        class func loadHomeViewController() ->  HomeViewController {
            return loadFromMain("HomeViewController") as! HomeViewController
        }
    }
1
Shan Shafiq

新しいVCを使用してinstantiateViewControllerWithIdentifierを使用して、AppDelegateからストーリーボードによって作成されたインスタンスにアクセスする場合:

  1. appDelegate.hでプロパティを作成し、それを使用するクラスからアクセスできるようにする@property (nonatomic, strong) myViewControllerClass*vC;
  2. myViewControllerClass.m内のviewDidLoadでAppDelegateの共有インスタンスにアクセスし、プロパティにself:を送ります:[AppDelegate sharedInstance].vC = self;

複雑なストーリーボードでこのソリューションを使用する必要がありましたが、簡単な方法でアクセスできないという事実を克服することはできませんすべて(または少なくとも必要なもの)識別子のアドレス指定。

0
Lookaji

もう1つ確認するのは、エラーをスローしているViewControllerにstoryboardIdentifierがある場合、ストーリーボードのxibファイルを確認できることです。

私の場合は識別子がありませんでしたが、追加するとエラーが停止しました

0
megaKertz