在Xcode6中使用IBDesignable創(chuàng)建自定義控件(翻譯)

英文原文地址

在 Xcode 的舊版本中,試圖創(chuàng)建一個自定義控件,并不是很容易,因為在IB中,并不能實時預覽到你的設計成果,只能在模擬器中測試。對于設計一個單一組件,可能需要花費大量時間。

Xcode6 的發(fā)布,蘋果為開發(fā)者構(gòu)建自定義控件推出了新功能IBDesignableIBInspectable,允許在IB中實時預覽設計成果。很明顯,這會給實際開發(fā)提升很高效率。

在本教程中,將介紹IBDesignable IBInspectable,以及展示如何利用這個新功能。除過創(chuàng)建demo示例沒有更好地方式來闡述這一新特性,因此,創(chuàng)建一個"Rainbow"自定義界面。


效果圖

IBDesignable和IBInspectable

使用IBDesignable和IBInspectable,開發(fā)者創(chuàng)建界面(或視圖)可以實時呈現(xiàn)在IB中。一般來說,為了使用這個新特性,你需要做的是創(chuàng)建一個UIView或者UIControl的子類,然后在定義類的前面加上@IBDesignable關鍵字。如果是OC,使用IB_DESIGNABLE宏。下面是Swift示例代碼:

@IBDesignable
class Rainbow: UIView {
}

在Xcode舊版本中,你可以在IB中編輯User Defined Runtime Attributes來改變一個對象的屬性(例如:layer.cornerRadius),問題是你需要確切知道屬性名。IBInspectable只需要一步,對一個可視化類的屬性前面加上IBInspectable關鍵字前綴,該屬性會在暴露在IB中,這就是一個更改屬性值更簡單的方法。


IB屬性

你如果使用Swift開發(fā)app,你需要做的只是在你選擇的屬性前面加上@IBInspectable關鍵字,下面是個示例代碼片段:

@IBInspectable var firstColor: UIColor = UIColor.blackColor() {
   // 值改變時更新UI
}

創(chuàng)建Xcode項目

創(chuàng)建一個新的Xcode項目,選擇Single View Application模板,起名為RainbowDemo,在此項目中,將使用Swift語言,因此,創(chuàng)建項目時不要忘記勾選。

完成后,選擇Main.storyboard文件,設置View Controller的根視圖View的背景顏色Hex Color值為38334C(或者任何你想要的顏色)。然后從對象庫中拖一個View放進View Controller,設置它的大小Width為600,Height為434,然后把它放在根視圖的中心,設置新視圖View和根視圖相同背景顏色。

提示:如果想改變RGB顏色值,只需打開調(diào)色板和切換到滑塊標簽來改變RGB值


設置背景顏色

在Xcode6中,為了適配各個iOS設備,你必須為視圖View配置自動布局約束。對于簡單的約束,你可以在自動布局菜單單擊Issues選項,選擇Add Missing Contraints,Xcode將自動為View添加布局約束。


添加約束

創(chuàng)建自定義View類

現(xiàn)在,你已經(jīng)在storyboard中創(chuàng)建了一個View,是時候創(chuàng)建自定義View類了。使用Cocoa Touch Class文件模板,創(chuàng)建自定義類文件,繼承自UIView,起名為"Rainbow"。


創(chuàng)建自定義View類

在自定義類中插入以下代碼:

import UIKit

class Rainbow: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

如前所述,這個可視化類是UIView的子類,讓自定義類實時呈現(xiàn),需要override上述兩個方法。然后,打開輔助編輯器,更改新拖的View的自定義類為Rainbow類。



實現(xiàn)IBDesignable控制

為了實現(xiàn)實時預覽,在自定義類前面加一個前綴@IBDesignable關鍵字

@IBDesignable 
class Rainbow: UIView {
    ...
}

這個關鍵字確實簡單,但是這簡單地關鍵字將使你的開發(fā)更加容易。接下來,添加一些設置顏色的屬性。在Rainbow類中插入以下代碼:

@IBInspectable var firstColor: UIColor = UIColor(red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0)
@IBInspectable var secondColor: UIColor = UIColor(red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0)
@IBInspectable var thirdColor: UIColor = UIColor(red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0)

在這里,我們預先定義每個屬性一個默認顏色,每次用戶更改它們的值時會重繪視圖。更重要的是,我們?yōu)槊總€屬性加了一個@IBInspectable關鍵字前綴,現(xiàn)在去IB的屬性檢查器,你可以直觀地發(fā)現(xiàn)這些屬性:


IB中的屬性

很酷,對吧?IBInspectable通過指示屬性,你可以使用顏色選擇器可視化地編輯它們。

在Rainbow類中,為了在屏幕上畫一個圓,插入以下代碼:

func addOval(lineWidth: CGFloat, path: CGPathRef, strokeStart: CGFloat, strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor, shadowRadius: CGFloat, shadowOpacity: Float, shadowOffset: 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.shadowRadius = shadowRadius
   arc.shadowOpacity = shadowOpacity
   arc.shadowOffset = shadowOffset
   layer.addSublayer(arc)
}

為了保證代碼的簡潔和可讀性,我們定義了依據(jù)方法調(diào)用者傳入?yún)?shù)來繪制一個完整的圓或者半圓的公共方法。利用CAShapeLayer類可以很簡單的畫一個圓或圓弧。你可以使用strokeStart和strokeEnd屬性控制渲染的開始和結(jié)束。通過改變strokeEnd的值在0.0到1.0之間,你可以繪制一個完整或者部分的圓。其余的屬性是只是用于設置渲染顏色,陰影顏色等,在CAShaperLayer官方文檔中可以查看更詳細的所有可用屬性。

接下來,添加以下方法:

override func drawRect(rect: CGRect) {
    // 添加圓弧
    addCircle(80, capRadius: 20, color: firstColor)
    addCircle(150, capRadius: 20, color: secondColor)
    addCircle(215, capRadius: 20, color: thirdColor)
}

func addCircle(arcRadius: CGFloat, capRadius: CGFloat, color: UIColor) {
    let x = CGRectGetMidX(bounds)
    let y = CGRectGetMidY(bounds)

    // 底部圓弧
    let pathBottom = UIBezierPath(ovalInRect: CGRectMake((x - (arcRadius/2)),
        (y - (arcRadius/2)), arcRadius, arcRadius)).CGPath
    addOval(20.0, path: pathBottom, strokeStart: 0, strokeEnd: 0.5,
        strokeColor: color, fillColor: UIColor.clearColor(),
        shadowRadius: 0, shadowOpacity: 0, shadowOffset: CGSizeZero)

    // 中間圓弧
    let pathMiddle = UIBezierPath(ovalInRect: CGRectMake((x - (capRadius/2)) - (arcRadius/2),
        (y - (capRadius/2)), capRadius, capRadius)).CGPath
    addOval(0.0, path: pathMiddle, strokeStart: 0, strokeEnd: 1.0,
        strokeColor: color, fillColor: color,
        shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffset: CGSizeZero)

    // 頂部圓弧
    let pathTop = UIBezierPath(ovalInRect: CGRectMake((x - (arcRadius/2)),
        (y - (arcRadius/2)), arcRadius, arcRadius)).CGPath
    addOval(20.0, path: pathTop, strokeStart: 0.5, strokeEnd: 1.0,
        strokeColor: color, fillColor: UIColor.clearColor(),
        shadowRadius: 0, shadowOpacity: 0, shadowOffset: CGSizeZero)
}

drawRect:方法默認什么也不做,為了在自定義View中畫圓,我們override此方法來實現(xiàn)自己的繪制代碼。addCircle:方法有三個參數(shù):arcRadius,capRadius和color。arcRadius是圓弧的半徑,capRadius是圓弧邊緣半徑。

addCircle:方法利用UIBezierPath畫圓弧的簡單工作原理:

  1. 首先,在底部畫了個半圓弧
  2. 接下來,在圓弧邊緣畫了一個完整的小圓
  3. 最后,畫了另一半圓弧

drawRect:方法中,我們調(diào)用了addCircle:方法三次,傳入的參數(shù)指定圓弧該怎樣畫:


畫圓弧原理

利用IBInspectable屬性,你可以在IB中自由改變每個圓弧的顏色,而不需要寫代碼:


顯然,你可以進一步利用@IBInspectable暴露arcRadius屬性,便可以在IB中修改繪制圓弧半徑。


修改半徑

總結(jié)

通過本教程后,你現(xiàn)在了解了在Xcode6中如何利用IBDesignable和IBInspectable實時預覽界面。利用這個新特性,你可以更高效創(chuàng)建自定義組件。

RainbowDemo地址

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,151評論 4 61
  • 曾經(jīng)想實現(xiàn)自定義的View,可以想系統(tǒng)自帶那樣擁有屬性,并且實時渲染,動態(tài)更新內(nèi)容,現(xiàn)在在Xcode6終于讓你可以...
    Oneruofeng閱讀 2,449評論 0 5
  • George Orwell. 《1984》DAY 7/20 Part2 Chapter1-2 這兩個章節(jié)主要寫了W...
    Jenner大江閱讀 180評論 0 0
  • 社交,對絕大多數(shù)人來說,時時刻刻都在發(fā)生,但是對社交的重視和維護,并不見得人人都有重視。 小學,初...
    桃拾壹閱讀 182評論 0 0
  • 證書有效性,一般要檢查三點: 驗證證書是否是否在有效期內(nèi)?檢查證書上有簽發(fā)起始時間和過期時間 思考:如何保證取到的...
    Laok17閱讀 5,887評論 0 0