web-dev-qa-db-ja.com

xibファイルからViewControllerをロードする

持っていた MyViewController.SwiftおよびMyViewController.xib MyViewControllerのレイアウトを提示します。

このView Controllerをロードするためのさまざまな方法を試しました:

//1
let myVC = UINib(nibName: "MyViewController", bundle:
       nil).instantiateWithOwner(nil, options: nil)[0] as? MyViewController

//2
let myVC = NSBundle.mainBundle().loadNibNamed("MyViewController", owner: self, options: nil)[0] as? MyViewController

//3
let myVC = MyViewController(nibName: "MyViewController", bundle: nil)

3番目は成功した初期化のみですが、前の2つはエラーの原因です。

キャッチされない例外「NSUnknownKeyException」によるアプリの終了、

理由: '[setValue:forUndefinedKey:]:このクラスは、キーXXXのキー値コーディングに準拠していません。

これらの読み込み方法の何が問題になっていますか?

27
bluenowhere

Swift

let myViewController = MyViewController(nibName: "MyViewController", bundle: nil)
self.present(myViewController, animated: true, completion: nil)

またはNavigation Controllerをプッシュ

self.navigationController!.pushViewController(MyViewController(nibName: "MyViewController", bundle: nil), animated: true)
67
Marcos Reboucas

File's Owner

File's Owner。あなたの場合、File's OwnerMyViewControllerでなければならない、またはsub-class

クラスFooで実行する場合、次のコード。

// If `self` is an instance of `Foo` class.
// In this case, `File's Owner` will be a `Foo` instance due to `self` parameter.
let myVC = NSBundle.mainBundle().loadNibNamed("MyViewController", owner: self, options: nil)[0] as? MyViewController

selfownerとして割り当てます。したがって、File's OwnerFooではなくMyViewControllerです。次に、Fooクラスの場合、それらのIBOutletFooに接続できません。そのため、例外がスローされます。

12
AechoLiu
extension UIViewController {
    static func loadFromNib() -> Self {
        func instantiateFromNib<T: UIViewController>() -> T {
            return T.init(nibName: String(describing: T.self), bundle: nil)
        }

        return instantiateFromNib()
    }
}

次のように使用します。

let testVC = TestVC.loadFromNib()
7
SamehDos

同じ問題がありました。自動生成されたxibにはUIViewが含まれていました。ビューを削除し、新しいView Controllerをxibに追加し、View Controllerクラスを目的のクラスに設定してから、コンセントを接続する必要があります。このすべての後、上記のコードを使用して、次のようにこのView Controllerのインスタンスを取得できます。

if let menuVC = Bundle.main.loadNibNamed("MenuViewController", owner: nil, options: nil)?.first as? MenuViewController {
            menuVC.profileType = profileType
            vc.present(menuVC, animated: true, completion: nil)
        }
2
Archangel

問題はメソッドにありません...おそらくいくつかのuielementにアウトレット(XXX)を接続したままにして、対応するコントローラーから削除しました...私は以下の例を追加しています... enter image description here

上記のボタンは現在コントローラに接続されていますが、アウトレットをコメントすると enter image description here

アプリがクラッシュする enter image description here

enter image description here

そのため、viewcontrollerにはないがxibファイルにあるアウトレット(xxx)を見つけてください。

2
Sanman

@AechoLiuの答えは素晴らしい。私は同じ質問をして、以下の修正でそれに答えました。

問題:

let vc1 = NSViewController(nibName: YDNibIdentifier.myplainvc, bundle: nil)

修正:

let vc1 = MyPlainViewController(nibName: YDNibIdentifier.myplainvc, bundle: nil)

.xibファイル内で正しく接続されていたにもかかわらず、誤ってNibファイルを間違ったClas(NSViewController)にキャストしていました。

0
rustyMagnet