2017-05-09 10 views
3

新しいインスタンスを初期化するのに使用できるUIViewControllerという拡張を作成しようとしています。私のプロジェクトの各View Controllerには、対応するストーリーボードがあります。一般的なUViewController初期設定の作成

すなわち

EditSomethingViewController.swift 
EditSomethingViewController.storyboard 

これは私がこれまで持っているものです。

extension UIViewController { 

    static func initalize() -> UIViewController? { 
     let name = String(self) 

     let storyboard = UIStoryboard(name: name, bundle: nil) 

     return storyboard.instantiateInitialViewController() 
    } 

} 

しかしこれは、私はそれを使用する場合、私はまだ応答をキャストしなければならないことを意味します。

すなわち

if let viewController = EditSomethingViewController.initalize() as? EditSomethingViewController { 
    // do something with view controller here 
} 

それは私が応答をキャストする必要がないことを意味し、このような方法で拡張機能を作成することは可能ですか?

p.s. Swift 2.3で書かれた古いプロジェクトに取り組むことで、サポートされている回答に感謝します。

+0

は、あなただけの関数の中にそれをキャストし、 'EditSomethingViewControllerを返すことができます'代わりに? –

答えて

1

私はこの拡張機能を使用

let controller = MyViewController.instantiateFromStoryboard() 
0

戻り値の型をSelfに変更して、メソッドを呼び出す型と一致させることができます。

これは私がこれまで行ってきた方法です。代わりにプロトコル拡張に入れる必要があります。

extension UIViewController 
{ 
    class func instantiateFromStoryboard(_ name: String = "Main") -> Self 
    { 
     return instantiateFromStoryboardHelper(name) 
    } 

    fileprivate class func instantiateFromStoryboardHelper<T>(_ name: String) -> T 
    { 
     let storyboard = UIStoryboard(name: name, bundle: nil) 
     let controller = storyboard.instantiateViewController(withIdentifier: String(describing: self)) as! T 
     return controller 
    } 
} 

使用法:

static func loadFromStoryboard() -> Self? { 
    let storyboard = UIStoryboard(name: NSStringFromClass(self), 
            bundle: Bundle(for: self)) 
    return storyboard.instantiateInitialViewController() as? Self 
} 
+0

いいえ、これはクラス拡張では機能しません。 – Sweeper

0

私はあなたがあなたのVCの一つ一つが手作業プロトコルに準拠したくないことを前提としています。それはあまりにも多くの仕事だろう:)

私はこれをテストしていませんが、これは動作するはずです:

protocol Initializable { 
    static func initalize() -> Self? 
} 

extension UIViewController: Initializable { 
    static func initalize() -> Self? { 
     let name = NSStringFromClass(self as! AnyClass) 

     let storyboard = UIStoryboard(name: name, bundle: nil) 

     return storyboard.getInitialVC(type: self) 
    } 
} 

extension UIStoryboard { 
    func getInitialVC<T: UIViewController>(type: T.Type) -> T? { 
     return instantiateInitialViewController() as? T 
    } 
} 
関連する問題