項(xiàng)目中經(jīng)常遇到一些設(shè)計(jì)使用圓角笔诵,不得不說這樣的設(shè)計(jì)經(jīng)常能夠?yàn)锳pp的視圖潤色不少锨咙!
通常做法
對于代碼黨來說,很簡單的加上一行代碼就能夠搞定:
view.layer.cornerRadius = 5
對于 Storyboard 狂魔原献,一般情況下廉邑,很多人會(huì)先把視圖拉一個(gè) IBOutlet 然后再到 awakeFromeNib:
或者 viewDidLoad:
方法中去設(shè)置圓角,代碼如下:
@IBOutlet weak var customView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
customView.layer.cornerRadius = 5
}
但是對代碼有一定潔癖的強(qiáng)迫癥患者來說议泵,這樣的做法經(jīng)常是要命的占贫!實(shí)在無法忍受一個(gè)小小圓角都不能在IB中設(shè)置,需要另外單獨(dú)加一行代碼來完成先口,違背了低耦合型奥,高內(nèi)聚的原則。有人馬上提出建議碉京,那就使用IB的運(yùn)行時(shí)屬性(Runtime Attributes)厢汹,有些新手可能對?它還不太熟悉:
這的確也是個(gè)不錯(cuò)的方法,可以達(dá)到高內(nèi)聚的效果谐宙。不過用過的人都知道烫葬,很容易就把 keyPath 拼寫錯(cuò),而且由于這個(gè)設(shè)置和其他屬性的設(shè)置分開凡蜻,可讀性可以說很差很差搭综。那有沒有什么好的方法呢?
最佳實(shí)踐
Xcode6之后運(yùn)行時(shí)屬性升級(jí)到了 @IBInspectable 划栓,利用這個(gè)我們可以給 UIView 添加一個(gè)屬性兑巾,然后就可以在IB中進(jìn)行設(shè)置,例如我們想給 ViewController 添加一個(gè)數(shù)值到IB中設(shè)置忠荞,在上述代碼的最前面插入代碼:
@IBInspectable var customNumber: Int?
然后我們就能在屬性檢查器上看到如圖所示內(nèi)容蒋歌,很容易地對數(shù)值進(jìn)行設(shè)置:
@IBInspectable 還支持以下類型屬性:
- Boolean
- Number
- String
- Point
- Size
- Rect
- Range
- Color
- Image
- nil
回到正題,我們視圖的圓角該怎么實(shí)現(xiàn)呢委煤?也許你們馬上想到了繼承堂油,實(shí)現(xiàn)一個(gè) UIView 的基類,基類中添加圓角的 @IBInspectable 屬性碧绞。但這樣你馬上嗅到了不好的味道府框,你所有想要使用該屬性的視圖都要繼承自該基類,那豈不是更加麻煩讥邻!
其實(shí)最好的解決方法你應(yīng)該心里有數(shù)迫靖,如果說在 Object-C 中給已有的類添加方法癣诱,你肯定馬上能想到 Category !不過可能有些人還沒不清楚應(yīng)該如何在 Category 中添加屬性袜香。由于這里我們用的是 Swift ,稍后我們再說OC中應(yīng)該如何實(shí)現(xiàn)鲫惶。 Swift 中應(yīng)該使用 extension 來對 UIView 進(jìn)行擴(kuò)展蜈首,并且我們需要添加 @IBInspectable 來擴(kuò)展屬性,所以我們需要同時(shí)實(shí)現(xiàn) setter & getter 欠母,創(chuàng)建一個(gè)命名為 UIView+O2CornerRadius.swift
的文件欢策,代碼如下:
import UIKit
extension UIView {
@IBInspectable var cornerRadius: CGFloat {
get {
return layer.cornerRadius
}
// also set(newValue)
set {
layer.cornerRadius = newValue
}
}
}
只需要如此簡單地添加一個(gè)擴(kuò)展,不需要 import 赏淌,不必任何多余代碼踩寇,我們就可以非常非常方便地在任意IB的屬性檢查器中對圓角進(jìn)行設(shè)置了!這不就是我們夢寐以求的解耦嗎六水?0乘铩!:)
實(shí)際上掷贾, @IBInspectable 是對運(yùn)行時(shí)的一種擴(kuò)展睛榄,你所有的設(shè)置都會(huì)在上述提到的運(yùn)行時(shí)屬性(Runtime Attributes)有所體現(xiàn)。
接下來做什么想帅?
我們還可以增加很多內(nèi)容的擴(kuò)展场靴,例如陰影、邊框港准、邊框顏色等等旨剥!學(xué)會(huì)了這樣的奇淫技巧,還不趕緊到你的項(xiàng)目中去實(shí)踐浅缸!
說說 Object-C 的代碼實(shí)現(xiàn)轨帜,我們使用 Category 同樣需要同時(shí)實(shí)現(xiàn) setter & getter :
//UIView+O2CornerRadius.h
@interface UIView (O2CornerRadius)
@property (nonatomic, assign) IBInspectable CGFloat cornerRadius;
@end
//UIView+O2CornerRadius.m
@implementation UIView (O2CornerRadius)
- (void)setCornerRadius:(CGFloat)cornerRadius
{
self.layer.cornerRadius = cornerRadius;
}
- (CGFloat)cornerRadius
{
return self.layer.cornerRadius;
}
@end