Xcode 6からインタフェースビルダ (ストーリーボード) 向けに2つの修飾子@IBDesignableと@IBInspectableが追加されました。
この2つを使うことでストーリーボード上で実際に描画されたビューを見たり、ビューの属性を変更したりできるようになるので、試してみました。
なお、WWDC 2014のセッション「What’s new in Xcode 6」内の解説が詳しいです。
簡単な紹介
とりあえず使ってみましょう。
UIViewを継承したクラスを作成して、それに@IBDesignableを付けます。
また、インスタンス属性を作成して、それには@IBInspectableを付けます。
@IBDesignable class ShapeView: UIView {
@IBInspectable var cornerRadius: CGFloat {
get { return self.layer.cornerRadius }
set { self.layer.cornerRadius = newValue }
}
@IBInspectable var shapeBackgroundColor: UIColor? {
get { return UIColor(CGColor: self.layer.backgroundColor) }
set { self.layer.backgroundColor = newValue?.CGColor }
}
}
次に、UIViewをストーリーボードに貼り付けてから、そのCustom ClassをShapeViewにします。
すると、Desinablesという項目が出現して、その値が「Up to date」になります。Up to dateは最新のコードと同じ表示がなされているということを意味しています。
Attributesインスペクタに移動すると@IBInspectableで指定したプロパティが出現しています。
ここの値を変更すると、ストーリーボード上での表示もすぐに反映されます。
注意事項
現在のところ、@IBDesignableと@IBInspectableには次のような制限があるみたいです。
@IBDesignableになるには、UIViewかNSViewの直接のサブクラスである必要がある (UITableViewCellを@IBDesignableにしても表示されない)。@IBInspectableになれる型はUser Defined Runtime Attributesと同じ。enumは利用できない。- 画像などを表示する必要があって、とりあえずプレースホルダを設定させたいときなどは
prepareForInterfaceBuilderを使うことができる (後の例では利用しています) - WWDCではウィジェット用のフレームワークを作る必要があるように言っているが、少なくともSwiftでは不要っぽい
なお、@IBInspectableで設定した値は、IdentityインスペクタのUser Defined Runtime Attributesにも表示されるようになります。
なので、実は@IBInspectableはUser Defined Runtime Attributesよりちょっと楽に値が設定できるだけだったりします。
ウィジェットのデバッグ
- そのウィジェットのブレークポイントを設置
- ウィジェットのストーリーボード上で選択
- メニューから、Edit → Debug Selected Views
複雑な例
サブビューがあっても@IBDesignableが有効かどうかを試してみました。
@IBDesignable class EditTableViewCell: UIView {
let titleLabel = UILabel()
let textField = UITextField()
@IBInspectable var title: String {
get { return titleLabel.text! }
set { titleLabel.text = newValue }
}
@IBInspectable var placeholder: String? {
get { return textField.placeholder }
set { textField.placeholder = newValue }
}
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
override func prepareForInterfaceBuilder() {
if titleLabel.text == nil {
title = "titleを入力してください"
}
if textField.placeholder == nil {
placeholder = "placeholderを入力してください"
}
}
private func setupView() {
addSubview(titleLabel)
addSubview(textField)
titleLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
textField.setTranslatesAutoresizingMaskIntoConstraints(false)
addConstraints(layoutConstraints())
}
}
試しにテーブルビューの静的表示でセルに貼り付けてみました。プロパティに値をセットしていないので、prepareForInterfaceBuilderで指定した値が表示されています。
関連リンク
紹介したコードは次のリポジトリに上げています。







0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。