機能自体は良いが色々とウザい。
簡単なViewを作るのに2、3時間費やしてしまったのでメモをアップする。
- InterfaceBuilder(以降IB)表示時にビルドがかかり非常に重くなる
- 普通のViewでは不要な考慮が色々必要
- IB上でエラーが起きても原因が分かりづらい
- IB上でエラーが起きるとXcodeがおかしくなることがある
IBを開くびにビルドがかかる
IBDesignableを修正してIBを開くとビルドがかかる。
IB上でフォントサイズを変えるだけでビルドがかかる。
メニューの “Editor” > “Automatically Refresh Views” のチェックを外すと自動でビルドがかからなくなる。
IB上で手動でViewをリフレッシュしたい場合、メニューの “Editor” > “Refresh All Views” を実行。
画像リソースを使えない
#imageLiteral
で画像を参照するとIB上でクラッシュする。
UIImage(named: "xxxxx”)
の形でUIImageを作ってもIB上では画像が表示されない。
IBDesignableでプログラムから画像を指定する場合、Bundleを動的に作って指定してやる必要がある。
let bundle = Bundle(for: type(of: self))
let image = UIImage(named: "pulldown_arrow", in: bundle, compatibleWith: nil)
エラーの原因が分かりづらい
エラーが出た場合、とりあえずIB上で問題のViewを選択して、メニューの “Editor” > “Debug Selected Views” を実行。
すると問題のViewがデバッガー付きで実行されるので、エラー箇所で停止してエラーの原因を確認することができる。
init で色などを設定してもIB上に反映されない
init
でbackgroundColorなどを設定しても、initが実行された後にIBで設定された色に上書きされてしまいIB上では反映されない。(通常起動なら反映される)
class RedView: UIView {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
func setup() {
backgroundColor = UIColor.red
}
}
これを回避するには IB の設定が終わった後に、色などの設定を行う必要がある。
IBの設定時に prepareForInterfaceBuilder
が呼ばれるので、これをoverrideして対応することができる。
class RedView: UIView {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setup()
}
func setup() {
backgroundColor = UIColor.red
}
}
ただし、prepareForInterfaceBuilder
は通常の実行時は呼ばれないので、init
でも同じ設定をする必要がある。