読者です 読者をやめる 読者になる 読者になる

tomoyaonishiのブログ

iOSのことを中心に・・・その他もあるよ!

Swiftでxibで作成したカスタムビューのインスタンスを簡単に返す

Objective-Cではxibで作成したカスタムビューのインスタンスを以下のように生成して利用していました。

しかし、Swiftではinitのなかでselfに代入することはできないようです。(もし出来るならやり方教えてください。) なので以下のような書き方でxibからロードしたインスタンスを返すことはできないようです。

let view = CustomView()

f:id:tomoyaonishi:20150320161312p:plain

回避策としてジェネリクスを使ってどんなカスタムビューのインスタンスでも返すことができる関数を作ってみました。

func InstantiateCustomView<T: UIView>(classToCreate: AnyClass) -> T {
    let view = UINib(nibName: NSStringFromClass(classToCreate), bundle: nil).instantiateWithOwner(nil, options: nil)[0] as T
    
    return view
}

使い方は簡単です。

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let view: CustomView = InstantiateCustomView(CustomView)
        self.view.addSubview(view)
    }

}

返り値の型Tが確定しないといけないので、 let view: CustomViewのように型を定義して受け取ります。(スマートじゃない。。)

CustomViewは以下のように定義しています。 

@objc(CustomView)
class CustomView: UIView {
    
}

@objcはCustomViewクラスのクラス名をObjC名前空間に"CustomView"という名前で書きだすという意味です。Swiftではクラス名は"モジュール名.クラス名"となってしまい、NSStringFromClassの返り値をそのままnibNameに渡せません。@objcとつけることでNSStringFromClassで取得できるクラス名がモジュール名なしの形になります。

ちなみにInstantiateCustomView関数は<T: UIView>としているのでTはUIViewのサブクラス以外受け付けません。

もうちょっとスマートにしたいです。。。