iOS tutorial 8:使用IBInspectable 和 IBDesignable定制UI

參考: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)載請注明出處!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容