Objective-Cではxibで作成したカスタムビューのインスタンスを以下のように生成して利用していました。
しかし、Swiftではinitのなかでselfに代入することはできないようです。(もし出来るならやり方教えてください。) なので以下のような書き方でxibからロードしたインスタンスを返すことはできないようです。
let view = CustomView()
回避策としてジェネリクスを使ってどんなカスタムビューのインスタンスでも返すことができる関数を作ってみました。
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のサブクラス以外受け付けません。
もうちょっとスマートにしたいです。。。