【iOS】クラス名の文字列からViewControllerクラスを生成する方法
notwork_ios_stringtoclass
スポンサーリンク

String型のクラス名からUIViewControllerのインスタンスを生成する方法

画面名から画面ごとのViewControllerインスタンスを生成する方法

ヒーラー
クラス名からのクラス生成はできそうだけどUIViewControllerではひとくせあり

はじめに

画面の名前とViewControllerの名前は大抵の場合合せていることだと思います。
そこで、いくつもの画面を分岐して作成したい場合に、画面に合わせたViewControllerを共通化して作成したい場合がありました。

イメージとしては、Factoryクラスに画面名(クラス名)を渡すと相当のインスタンスを返してくれるというものです。

let firstVC = ViewControllerFactory.createViewController(classname: "First") as! FirstViewController
let secondVC = ViewControllerFactory.createViewController(classname: "Second") as! SecondViewController

対処方法

クラス名の文字列からクラスのインスタンスを生成するには、NSStringFromClassを使用すれば解決します。
例えばUIViewであれば、

let uiviewClass = NSClassFromString("UIView") as! UIView.Type
let view = uiviewClass.init()

しかし、UIViewControllerの場合は注意点があります。
クラス名の前にターゲット名が含まれている必要があります。

let myClass = NSClassFromString("MyProject.CustomViewController") as! UIViewController.Type
let viewController = myClass.init()

しかしながら、productionやdevelopなど環境ごとにターゲットを分けていると、ターゲット名を固定にする訳にもいきません。
更にターゲット名を取得する必要があります。

let targetname = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String
let vcname = targetname + "." + "CustomViewController"
let myClass = NSClassFromString(vcname) as! UIViewController.Type
let viewController = myClass.init()

Bundle.main.object(forInfoDictionaryKey: "CFBundleName")でターゲット名を取得できます。
これで、目的のクラス名の文字列からViewControllerインスタンスを生成することができます。

なお、作成したFactoryクラスは以下のようなイメージです。

class ViewControllerFactory {
    static func createViewController(screenname: String) -> UIViewController? {
        let targetname = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as! String
        let vcname = targetname + "." + screenname + "ViewController"
        guard let classType = NSClassFromString(vcname) as? UIViewController.Type else {
            return nil
        }
        let viewController = classType.init()
        return viewController
    }
}

スポンサーリンク

Twitterでフォローしよう

おすすめの記事