LoginSignup
42
18

More than 5 years have passed since last update.

IBDesignableがウザい

Last updated at Posted at 2018-02-21

機能自体は良いが色々とウザい。
簡単な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 でも同じ設定をする必要がある。

42
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
18