參考:appcode網(wǎng)站的書《Intermediate iOS Programming with Swift》 的Chapter 36
例子代碼:https://github.com/andyRon/LearniOSByProject/tree/master/P077-FancyButton
理解IBInspectable 和 IBDesignable
簡單地說,IBInspectable 就是允許開發(fā)者在IB的屬性檢查器中添加額外的選項。IBDesignable 能夠讓* IBInspectable* 添加的額外選項產(chǎn)生的變化在IB中實時顯示。以Button的圓角為例說明。
- 正常情況下,Button的圓角需要代碼:
button.layer.cornerRadius = 10.0
button.layer.masksToBounds = true
或者直接在IB的Identity檢查器的 user defined runtime attributes中添加:

注意到,這種修改不是實時,在IB中Button還是直角,只有運行后才是圓角。
- 以IBInspectable的方式。定義個繼承至
UIButton的類。
class RoundedCornerButton: UIButton {
@IBInspectable var cornerRadius: CGFloat = 0.0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
}
然后把button的class屬性修改成RoundedCornerButton:

發(fā)現(xiàn)這個button的屬性檢查器中多了Corner Radius。
注意:
cornerRadius屬性變成了Corner Radius,RoundedCornerButton類變成了 Rounded Corner Button,這是Xcode自動轉(zhuǎn)變的,開發(fā)者只需要依照swift的命名規(guī)范就可以了(類名是大寫開頭的駝峰命名規(guī)則,屬性名是小寫開頭的駝峰命名規(guī)則)

cornerRadius的類型是CGFloat,在屬性檢查器中就對應(yīng)數(shù)字的選擇。當(dāng)然不是所有類型都可以添加屬性檢查器中的,IBInspectable支持如下類型:
Int
CGFloat
Double
String
Bool
CGPoint
CGSize
CGRect
UIColor
UIImage
如果在類RoundedCornerButton前添加@IBDesignable,那在屬性檢查器中自定義的屬性變化就可以在IB中實時顯示了。
@IBDesignable class RoundedCornerButton: UIButton {
@IBInspectable var cornerRadius: CGFloat = 0.0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
}

創(chuàng)建Fancy Button
創(chuàng)建Fancy Button來更加深入的了解IBInspectable 和 IBDesignable
- 創(chuàng)建新項目FancyButton
- 下載圖標(biāo),也可以隨意圖標(biāo),拖進asset catalog
- 新建類
FancyButton,繼承至UIButton - 圓角,邊寬,邊的顏色。 更新
FancyButton:@IBDesignable class FancyButton: UIButton { @IBInspectable var cornerRadius: CGFloat = 0.0 { didSet { layer.cornerRadius = cornerRadius layer.masksToBounds = cornerRadius > 0 } } @IBInspectable var borderWidth: CGFloat = 0.0 { didSet { layer.borderWidth = borderWidth } } @IBInspectable var borderColor: UIColor = .black { didSet { layer.borderColor = borderColor.cgColor } } }

- Title
在FancyButton繼續(xù)添加屬性:@IBInspectable var titleLeftPadding: CGFloat = 0.0 { didSet { titleEdgeInsets.left = titleLeftPadding } } @IBInspectable var titleRightPadding: CGFloat = 0.0 { didSet { titleEdgeInsets.right = titleRightPadding } } @IBInspectable var titleTopPadding: CGFloat = 0.0 { didSet { titleEdgeInsets.top = titleTopPadding } } @IBInspectable var titleBottomPadding: CGFloat = 0.0 { didSet { titleEdgeInsets.bottom = titleBottomPadding } }

- 通過圓角可創(chuàng)建圓形button

- Image Padding
添加圖片邊距的屬性:@IBInspectable var imageLeftPadding: CGFloat = 0.0 { didSet { imageEdgeInsets.left = imageLeftPadding } } @IBInspectable var imageRightPadding: CGFloat = 0.0 { didSet { imageEdgeInsets.right = imageRightPadding } } @IBInspectable var imageTopPadding: CGFloat = 0.0 { didSet { imageEdgeInsets.top = imageTopPadding } } @IBInspectable var imageBottomPadding: CGFloat = 0.0 { didSet { imageEdgeInsets.bottom = imageBottomPadding } }

- 圖片靠右對齊
根據(jù)下圖關(guān)系,應(yīng)有imageEdgeInsets.left = self.bounds.width - imageView.bounds.width - imageRightPadding。

在FancyButton中添加如下代碼:
@IBInspectable var enableImageRightAligned: Bool = false
override func layoutSubviews() {
super.layoutSubviews()
if enableImageRightAligned, let imageView = imageView {
imageEdgeInsets.left = self.bounds.width - imageView.bounds.width - imageRightPadding
}
}
+ `enableImageRightAligned`屬性又來自動計算 `imageEdgeInsets.left`

- 顏色漸變
添加三個@IBInspectable屬性,并更新layoutSubviews:@IBInspectable var enableGradientBackground: Bool = false @IBInspectable var gradientColor1: UIColor = UIColor.black @IBInspectable var gradientColor2: UIColor = UIColor.white override func layoutSubviews() { super.layoutSubviews() if enableImageRightAligned, let imageView = imageView { imageEdgeInsets.left = self.bounds.width - imageView.bounds.width - imageRightPadding } if enableGradientBackground { let gradientLayer = CAGradientLayer() gradientLayer.frame = self.bounds gradientLayer.colors = [gradientColor1.cgColor, gradientColor2.cgColor] gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5) gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5) self.layer.insertSublayer(gradientLayer, at: 0) } }

漸變色需要運行后才能看到

本文標(biāo)題: iOS tutorial 8:使用IBInspectable 和 IBDesignable定制UI
本文作者: AndyRon
本文鏈接: http://andyron.com/2017/ios-tutorial-8-ibinspectable-ibdesignable.html
版權(quán)聲明: 本博客所有文章除特別聲明外,均采用 CC BY-NC-SA 3.0 許可協(xié)議。轉(zhuǎn)載請注明出處!