你有沒有嘗試過在舊版xcode裏建立過自定義控件?不是很容易。主要是由於你在Interface Builder(如下簡稱IB)裏看不到實時的效果,每次你要查看修改的效果,只能從新運行,這樣很麻煩,你可能要花數小時來設計一個簡單的控件。html
Xcode6帶來了一個新特性:在IB使用IBDesignable和IBInspectable自定義能夠實時預覽效果的控件。很是明顯,將能極大的提高產品開發效率。ios
在這個教程裏,我將給你介紹IBDesignbale和IBInspectable,同時給大家展現若是利用這些特性。沒有什麼辦法能夠舉個例子更詳細了。因此接下來咱們一塊兒來打造一個叫「彩虹」的自定義控件。git
有了IBDesignable和IBInspectable,開發者們容許在IB中構造實時渲染效果的界面(或視圖),通常來說,要使用這個新特性,你只要建立一個UIView或UIControl的子類,並在類前面加上@IBDesignable關鍵詞(swift),若是你使用的是Object-c,請用IB_DESIGNABLE宏代替,下面是swift的列子:github
@IBDesignable classRainbow: UIView{ }
在老版本xcode中,你能夠編輯用戶自定義的運行時屬性來改變對象的屬性(如:layer.conerRadius),麻煩的是你必須在IB中精確的輸入同名的屬性名稱,IBInspectable更加方便,你只要在類屬性聲明的屬性前面加上@IBInspectable,這個屬性自動會顯示在IB中,不用手工輸入,使得改變視圖對象的屬性更加直觀了。如圖編程
再重複一遍,若是你使用的swift開發app,你要作的只是在屬性前面加上@IBInspectable,例子swift
@IBInspectable varfirstColor:UIColor=UIColor.blackColor(){ // Update your UI when value changes }
還有疑問?別擔憂,跟着一塊兒作完這個Demo你就徹底懂了。xcode
選擇Single View Application模板新建一個工程,命名爲RainbowDemo。使用Swift編程語言。app
選中Main.storyboard,拖一個View控件到View Controller裏,修改背景色爲 #38334C(或隨便啥顏色),同時設置大小爲600x434。同時把整個容器View的背景色改爲與剛拖進來的View同樣的顏色。編程語言
小提示:如何設置RGB顏色?在顏色面板有Color Palette,拖動RGB色條來設置。ide
同時在xcode6裏必須使用自動佈局約束來支持各種型的ios設置,自動佈局在最新版的xocde裏很是的強大,簡單的約束,你只要點擊自動佈局按鈕,並選擇「Add Missing Contraints」,xcode將自動給視圖添加好約束。
新建一個Swift類型的源文件件,命名爲 Rainbow,替換爲如下代碼
importUIKit classRainbow: UIView{ required init(coder aDecoder:NSCoder){ super.init(coder:aDecoder) } override init(frame:CGRect){ super.init(frame:frame) } }
就像以前說的,它是一個UIView的子類。爲了看到實時效果,咱們將窗口分割成兩個視圖,使用assistant editor
而後在新開的窗口選擇Main.storyboard文件,記得修改下你以前拖到UIView視圖的控件的類名爲Rainbow,這樣跟你剛建立的swift源代碼是同一個類了。
第一步:在類前面加上@IBDesignable前綴,如
@IBDesignable classRainbow: UIView{ ... }
能夠看出來很簡單,但這個簡單的關鍵詞卻使得開發變成更加輕鬆了。下一步,咱們將要添加一些屬性,來設置圓的顏色,添加如下類屬性
@IBInspectable varfirstColor:UIColor=UIColor(red:(37.0/255.0),green:(252.0/255 ),blue:(244.0/255.0),alpha:1.0) @IBInspectable varsecondColor:UIColor=UIColor(red:(171.0/255.0),green:(250.0/2 55),blue:(81.0/255.0),alpha:1.0) @IBInspectable varthirdColor:UIColor=UIColor(red:(238.0/255.0),green:(32.0/255 ),blue:(53.0/255.0),alpha:1.0)
同時也預約義了一些默認顏色,而且當每次修改屬性時重繪視圖。最重要的是,咱們在每一個屬性前面加上了關鍵詞@IBInspectable,此時你在IB面板上,你將看到這些屬性。
Cool吧,有了IBInspector作指示器,你能夠在可視化視圖裏調整屬性了。
下面是實現畫一個圓的代碼
func addOval(lineWidth: CGFloat, path: CGPathRef, strokeStart: CGFloat, strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor, shadowRadius: CGFloat, shadowOpacity: Float, shadowOffsset: CGSize) { let arc = CAShapeLayer() arc.lineWidth = lineWidth arc.path = path arc.strokeStart = strokeStart arc.strokeEnd = strokeEnd arc.strokeColor = strokeColor.CGColor arc.fillColor = fillColor.CGColor arc.shadowColor = UIColor.blackColor().CGColor arc.shadowRadius = shadowRadius arc.shadowOpacity = shadowOpacity arc.shadowOffset = shadowOffsset layer.addSublayer(arc) }
爲了更簡潔和可讀性,咱們建立了一個畫出半圓或全圓的方法,主要使用的是CAShapeLayer類,你可使用strokeStart和strokeEnd來控制起始,調用strokeEnd的範圍(0.1至1)你就能夠畫出一部分圓或全圓出來了。剩下的其它代碼是設置顏色和線條、陰影顏色等。你能夠點此此處查看CAShapeLayer的全部屬性。
下面添加其它具體實現代碼
override func drawRect(rect: CGRect) { // Add ARCs self.addCirle(80, capRadius: 20, color: self.firstColor) self.addCirle(150, capRadius: 20, color: self.secondColor) self.addCirle(215, capRadius: 20, color: self.thirdColor) } func addCirle(arcRadius: CGFloat, capRadius: CGFloat, color: UIColor) { let X = CGRectGetMidX(self.bounds) let Y = CGRectGetMidY(self.bounds) // Bottom Oval let pathBottom = UIBezierPath(ovalInRect: CGRectMake((X - (arcRadius/2)), (Y - (arcRadius/2)), arcRadius, arcRadius)).CGPath self.addOval(20.0, path: pathBottom, strokeStart: 0, strokeEnd: 0.5, strokeColor: color, fillColor: UIColor.clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero) // Middle Cap let pathMiddle = UIBezierPath(ovalInRect: CGRectMake((X - (capRadius/2)) - (arcRadius/2), (Y - (capRadius/2)), capRadius, capRadius)).CGPath self.addOval(0.0, path: pathMiddle, strokeStart: 0, strokeEnd: 1.0, strokeColor: color, fillColor: color, shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSizeZero) // Top Oval let pathTop = UIBezierPath(ovalInRect: CGRectMake((X - (arcRadius/2)), (Y - (arcRadius/2)), arcRadius, arcRadius)).CGPath self.addOval(20.0, path: pathTop, strokeStart: 0.5, strokeEnd: 1.0, strokeColor: color, fillColor: UIColor.clearColor(), shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero) }
默認的drawRect什麼也沒作,爲了在UIView上畫一個圓,必須本身實現drawRect方法,addCircle()方法須要三個參數:arcRadius, capRadius 和 color。arcRadius是圓的半徑,capRadius是彩虹上面小圓蓋的半徑。
addCircle()使用了UIBezierPath(貝塞爾曲線)來畫弧,流程是:
在drawRect方法裏,咱們使用不一樣的顏色和半徑調用了addCircle三次,下圖展現了依次的效果
提示:若是你想進一上了解UIBezierPath,請點擊
有了IBInspectable屬性你能夠自由的在IB裏控制樣式而沒必要一頭扎進代碼裏了。
作完這個練習,但願你能掌握xcode6的IBDesignable和IBInspectable使用。有了這個Interface Builder的實時效果,將提供給你一個更加有效率的自定義組件的方法。
翻譯:朱淦 350050183@qq.com 2016.7.20