UIEdgeInsetsを(強引に)@IBInspectable化する

@IBInspectableで入力できる型は、User Defined Runtime Attributesで指定できる型と同じ、とXcodeのドキュメントには書かれています。つまり、Localized StringやNilを除く以下の型を指定できます。

値の型 オブジェクト エディタ上の状況
Boolean Bool チェックボックス。チェックするとtrue
Number Int, Float, CGFloat, etc. 数値入力フィールド。非数値を入力するとエラーダイアログを表示する
String String 文字列入力フィールド
Point CGPoint CGPointとしてxyそれぞれを入力するフィールド
Size CGSize CGSizeとしてwidthheightそれぞれを入力するフィールド
Rect CGRect CGRectとしてxywidthheightそれぞれを入力するフィールド
Range NSRange NSRangeとしてのlocationrangeを入力するフィールド。NSUInteger相当
Color CGColor カラーパレット
Image UIImage(iOS) / NSImage(OS X) 画像

しかしこの一覧にない型、たとえばUIEdgeInsetsなどは、扱う値の1つ1つが設定可能な型(CGFloat)ですが@IBInspectableの効果を得られません。

なんとかできないかなと、たとえばこんなコードを考えてみました。

public var trigerPadding: UIEdgeInsets = UIEdgeInsetsZero

@IBInspectable public var trigerPaddingTop: CGFloat {
    get { return trigerPadding.top }
    set { trigerPadding = UIEdgeInsets(top: newValue,
                                       left: trigerPadding.left,
                                       bottom: trigerPadding.bottom,
                                       right: trigerPadding.right) }
}

@IBInspectable public var trigerPaddingLeft: CGFloat {
    get { return trigerPadding.left }
    set { trigerPadding = UIEdgeInsets(top: trigerPadding.top,
                                       left: newValue,
                                       bottom: trigerPadding.bottom,
                                       right: trigerPadding.right) }
}

@IBInspectable public var trigerPaddingBottom: CGFloat {
    get { return trigerPadding.bottom }
    set { trigerPadding = UIEdgeInsets(top: trigerPadding.top,
                                       left: trigerPadding.left,
                                       bottom: newValue,
                                       right: trigerPadding.right) }
}

@IBInspectable public var trigerPaddingRight: CGFloat {
    get { return trigerPadding.right }
    set { trigerPadding = UIEdgeInsets(top: trigerPadding.top,
                                       left: trigerPadding.left,
                                       bottom: trigerPadding.bottom,
                                       right: newValue) }
}

すこし長いですがとても単純なことをしているだけで、単にUIEdgeInsetsの1つ1つの計算型プロパティを用意して、大元である変数trigerPaddingの値にアクセスしているのみです。

とはいえ、これで下のスクリーンショットのように設定できるようになります。これはこれでなかなか便利です。

f:id:swiftlife:20160327221435p:plain