web-dev-qa-db-ja.com

SwiftのストーリーボードでUIViewController XIBファイルをロードできません

私は読んだ XCodeストーリーボードを使用して、そのデザインにXIBを使用するビューコントローラをインスタンス化する だが、これをSwift(Xcode 6 Beta 6を使用)で機能させるのに問題がある)私は何か間違ったことをしたのか、この機能がもう利用できないのかと思っています。

上記のアプローチを示す単純なリポジトリ https://github.com/jer-k/StoryboardTesting-Swift を作成しました。

私はinitに追加してオーバーライドすることで問題を解決することができました

required init(coder aDecoder: NSCoder) {
    super.init(nibName: "TestViewController", bundle: NSBundle.mainBundle())
}

しかし、ストーリーボードにこれを処理させることがまだ可能かどうか疑問に思っています。上記のコードを使用してすべてのUIViewControllersを継承するスーパークラスを作成することは、世界で最も厄介なことではありませんが、この時点で興味があるだけです。

23
TheJer

発生したのは、ビューコントローラがSeedクラスの場合、Swift 5がメカニズムを壊し、ビューコントローラがxibを名前で検索できるようになったことです。その理由は、Swiftの考えでは、クラスの名前は、クラスに付けた名前(およびxibファイルに付けた名前)と同じではないためです。特にモジュール名を前に付けることにより、名前が「マングル」されています(つまり、Swiftクラスには名前空間があります)。

3つの回避策を提供します。

  • あなたの回避策は良いものです(名前で.xibファイルを明示的にロードしてください)

  • .xibファイルに名前を付けますMyModule.TestViewController.xib。ここで、MyModuleはバンドルの名前(つまり、プロジェクトの名前)です(これがApple助言しますが、私はそれが嫌いです)

  • ビューコントローラーのclass宣言の前に@objc(TestViewController)を使用して、メカニズムを壊している名前のマングリングを克服します(これは私が好むアプローチです)

ここで私の議論を参照してください: https://stackoverflow.com/a/25163757/341994 そこからリンクされている私のさらなる議論: https://stackoverflow.com/a/25152545/ 341994

[〜#〜] edit [〜#〜]このバグはiOS 9ベータ4で修正されています。nibファイルの検索が失敗した場合、iOS 9は削除されますモジュール名はView Controllerのクラス名から外れ、nibファイル検索を2回実行します。

40
matt

別の答えは:

override func loadView() {
    if #available(iOS 9, *) {
        super.loadView()
    } else {
        let classString = String(self.dynamicType)
        NSBundle.mainBundle().loadNibNamed(classString, owner: self, options: nil)
    }
}

リンク: http://japko.net/2014/09/08/loading-Swift-uiviewcontroller-from-xib-in-storyboard/

編集:

override var nibName: String? {
    get {
        let classString = String(self.dynamicType)
        return classString
    }
}
override var nibBundle: NSBundle? {
    get {
        return NSBundle.mainBundle()
    }
}

これはより美しく見えます。 iOS 8/9で動作します(おそらくiOS 7でも動作します...)))

2
Dmitry Coolerov