玩轉(zhuǎn)swift -- UIKit 之 UIColor

前言

UIColor類是UIKit中用來存儲(chǔ)顏色數(shù)據(jù)的一個(gè)類,想要清晰的了解這個(gè)類中的相關(guān)屬性、方法,則需要先了解一個(gè)名詞:顏色空間

不同的設(shè)備處理顏色的方式是不同的, 每個(gè)設(shè)備都有他所支持的顏色范圍, 在一個(gè)設(shè)備上產(chǎn)生的顏色可能在另一臺(tái)設(shè)備上無法提供.所以,不同的設(shè)備就可能會(huì)具有不同的顏色空間,去解析相應(yīng)的顏色數(shù)據(jù)(比如UIColor)。

特別的,在iOS系統(tǒng)中,必須使用設(shè)備顏色空間(device color space)

在iOS 10之前的iOS版本上,以及在iOS 10之前的iOS版本上鏈接的應(yīng)用程序,可以在兩個(gè)顏色空間之一中創(chuàng)建和返回顏色:

Device-Dependent Gray
Device-Dependent RGB

iOS 10之后或之后連接,并且在iOS 10或更高版本上運(yùn)行,則顏色將在擴(kuò)展顏色空間中創(chuàng)建:

kCGColorSpaceExtendedGray
kCGColorSpaceExtendedSRGB

CoreGraphics中有個(gè)CGColorSpace類, 這個(gè)類可以用來獲取不同的設(shè)備顏色空間,舉例(三個(gè)比較常見的顏色空間)如下:

// 一個(gè)device-dependent 灰度顏色空間
@available(iOS 2.0, *)
public func CGColorSpaceCreateDeviceGray() -> CGColorSpace
// 一個(gè)device-dependent RGB顏色空間
@available(iOS 2.0, *)
public func CGColorSpaceCreateDeviceRGB() -> CGColorSpace
//  一個(gè)device-dependent CMYK顏色空間
@available(iOS 2.0, *)
public func CGColorSpaceCreateDeviceCMYK() -> CGColorSpace

然后還要了解的是 UIColor、CGColor、CIColor 之間的關(guān)系及轉(zhuǎn)化,本篇文章主要講 UIColor 的相關(guān)知識(shí),這篇文章對于三者之間的關(guān)系講的很詳盡,自己就不重復(fù)造輪子了,假如你理解了顏色空間與顏色數(shù)據(jù)之間的關(guān)系,那么這篇文章也就很好理解了。

進(jìn)入正題(基于iOS 10)

一、創(chuàng)建系統(tǒng)顏色

extension UIColor {
    // 在淺色背景上顯示文本的系統(tǒng)顏色。
    open class var lightText: UIColor { get } 
    // 在深色背景上顯示文本的系統(tǒng)顏色。
    open class var darkText: UIColor { get } 
    // 分組表的背景的系統(tǒng)顏色。
    open class var groupTableViewBackground: UIColor { get }
}

測試代碼如下:

// 測試創(chuàng)建系統(tǒng)顏色
func testCreateSystemColor() {
    
    // 顏色空間:UIExtendedGrayColorSpace    
    self.addImageView(color: UIColor.darkText);
    self.addImageView(color: UIColor.lightText);
    
    // 顏色空間:UIExtendedSRGBColorSpace
    self.addImageView(color: UIColor.groupTableViewBackground);
}
    
// 添加imageView
func addImageView(color: UIColor) {
        
    let imageView = UIImageView.init(frame: CGRect.init(x: 40, y: 80 + self.viewIndex * 40, width: 200, height: 20));
    imageView.backgroundColor = color;
    self.view.addSubview(imageView);
    print(color);
    self.viewIndex += 1;
}

結(jié)果如下:

UIExtendedGrayColorSpace 0 1
UIExtendedGrayColorSpace 1 0.6
UIExtendedSRGBColorSpace 0.937255 0.937255 0.956863 1

1

二、使用預(yù)定義顏色創(chuàng)建顏色對象

// 黑色
open class var black: UIColor { get } 
// 深灰
open class var darkGray: UIColor { get } 
// 淺灰
open class var lightGray: UIColor { get } 
// 白色
open class var white: UIColor { get }
// 灰色
open class var gray: UIColor { get } 
// 紅色
open class var red: UIColor { get } 
// 綠色
open class var green: UIColor { get } 
// 藍(lán)色
open class var blue: UIColor { get } 
// 藍(lán)綠色
open class var cyan: UIColor { get } 
// 黃色
open class var yellow: UIColor { get } 
// 紫紅色
open class var magenta: UIColor { get } 
// 橘黃色
open class var orange: UIColor { get } 
// 紫色
open class var purple: UIColor { get } 
// 褐色
open class var brown: UIColor { get } 
// 透明色
open class var clear: UIColor { get } 

測試代碼如下:

// 測試使用預(yù)定義顏色創(chuàng)建顏色對象
func testUsePreColorCreateColor() {
        
    // 顏色空間:UIExtendedGrayColorSpace
    self.addImageView(color: UIColor.black);
    self.addImageView(color: UIColor.darkGray);
    self.addImageView(color: UIColor.lightGray);
    self.addImageView(color: UIColor.white);
    self.addImageView(color: UIColor.gray);
    self.addImageView(color: UIColor.clear);

    // 顏色空間:UIExtendedSRGBColorSpace
    self.addImageView(color: UIColor.red);
    self.addImageView(color: UIColor.green);
    self.addImageView(color: UIColor.blue);
    self.addImageView(color: UIColor.cyan);
    self.addImageView(color: UIColor.yellow);
    self.addImageView(color: UIColor.magenta);
    self.addImageView(color: UIColor.orange);
    self.addImageView(color: UIColor.purple);
    self.addImageView(color: UIColor.brown);
}

測試結(jié)果如下

UIExtendedGrayColorSpace 0 1
UIExtendedGrayColorSpace 0.333333 1
UIExtendedGrayColorSpace 0.666667 1
UIExtendedGrayColorSpace 1 1
UIExtendedGrayColorSpace 0.5 1
UIExtendedGrayColorSpace 0 0
UIExtendedSRGBColorSpace 1 0 0 1
UIExtendedSRGBColorSpace 0 1 0 1
UIExtendedSRGBColorSpace 0 0 1 1
UIExtendedSRGBColorSpace 0 1 1 1
UIExtendedSRGBColorSpace 1 1 0 1
UIExtendedSRGBColorSpace 1 0 1 1
UIExtendedSRGBColorSpace 1 0.5 0 1
UIExtendedSRGBColorSpace 0.5 0 0.5 1
UIExtendedSRGBColorSpace 0.6 0.4 0.2 1

2

三、在特定顏色空間中創(chuàng)建自定義UIColor對象

// UIExtendedGrayColorSpace 灰度分量
public init(white: CGFloat, alpha: CGFloat)
// UIExtendedSRGBColorSpace HSB顏色空間分量
public init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat)
// UIExtendedSRGBColorSpace RGB顏色空間分量
public init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
// UIDisplayP3ColorSpace RGB分量
@available(iOS 10.0, *)
public init(displayP3Red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)

測試代碼如下:

// 測試在特定顏色空間創(chuàng)建UIColor
func testCreateColorWithSpecialColorSpace() {
        
    self.addImageView(color: UIColor.init(white: 0.3, alpha: 1.0));
    self.addImageView(color: UIColor.init(hue: 0.3, saturation: 0.5, brightness: 0.7, alpha: 1.0));
    self.addImageView(color: UIColor.init(red: 0.3, green: 0.5, blue: 0.7, alpha: 1.0));
    self.addImageView(color: UIColor.init(displayP3Red: 0.3, green: 0.5, blue: 0.7, alpha: 1.0));
}

結(jié)果如下:

UIExtendedGrayColorSpace 0.3 1
UIExtendedSRGBColorSpace 0.42 0.7 0.35 1
UIExtendedSRGBColorSpace 0.3 0.5 0.7 1
UIDisplayP3ColorSpace 0.3 0.5 0.7 1

注意:iOS 10后,通過圖形堆棧擴(kuò)展這種方式比以往支持廣色域的顯示設(shè)備更加容易。現(xiàn)在對UIKit擴(kuò)展可以在sRGB的色彩空間下工作,性能更好,也可以在更廣泛的色域來搭配sRGB顏色。

四、以現(xiàn)有的顏色數(shù)據(jù)創(chuàng)建UIColor對象

// 由指定的Quartz顏色生成一個(gè)UIcolor對象
public init(cgColor: CGColor)
// 由指定的Core Image顏色生成一個(gè)UIcolor對象
@available(iOS 5.0, *)
public init(ciColor: CIColor)
// 創(chuàng)建并返回一個(gè)與原Color相同顏色空間和組件值得顏色對象,并新添了透明度。
open func withAlphaComponent(_ alpha: CGFloat) -> UIColor

測試代碼如下

// 測試 color to color
func testColorToColor() {
        
    // CGColor -> UIColor
    self.addImageView(color: UIColor.init(cgColor: CGColor.init(colorSpace: CGColorSpaceCreateDeviceCMYK(), components: [1,1,0,0,1])!));
        
    // CIColor -> UIColor
    self.addImageView(color: UIColor.init(ciColor: CIColor.gray()));
        
    // UIColor ->UIColor(+alpha)
    self.addImageView(color: UIColor.red.withAlphaComponent(0.5));
}

測試結(jié)果如下:

kCGColorSpaceModelCMYK 1 1 0 0 1 
CIColor 0.5 0.5 0.5 1
UIExtendedSRGBColorSpace 1 0 0 0.5
4

五、由Image轉(zhuǎn)為Color

// image -> color
public init(patternImage image: UIImage)

測試代碼如下:

// 測試 image -> color
func imageToColor() {
        
    let color = UIColor.init(patternImage: UIImage.init(named: "imageToColor")!)
    let imageView = UIImageView.init(frame: CGRect.init(x: 40, y: 80, width: 158, height: 154));
    imageView.backgroundColor = color;
    self.view.addSubview(imageView);
    print(color);
}

測試結(jié)果如下:

kCGColorSpaceModelPattern 1 

5

建議:在實(shí)際項(xiàng)目中盡量避免使用這種方式加載加圖片,因?yàn)檫@種加載方式會(huì)比直接加載圖片占用更大的內(nèi)存。

六、設(shè)置圖形上下文的繪圖顏色

// 同時(shí)設(shè)置畫筆顏色和填充顏色
open func set()
// 設(shè)置填充顏色
open func setFill()
// 設(shè)置畫筆顏色
open func setStroke()

測試代碼如下:

// 測試設(shè)置圖形上下文的繪圖顏色
func testDrawColor() {
        
    let pathView = PathView.init(frame: self.view.bounds);
    self.view.addSubview(pathView);
}

PathView.swift內(nèi):

override func draw(_ rect: CGRect) {
        
    let path = UIBezierPath();
        
    path.addArc(withCenter: self.center, radius: 100.0, startAngle: 0, endAngle: 180.0, clockwise: true);
    path.lineWidth = 5.0;
    // 設(shè)置填充顏色    
    UIColor.red.setFill();
    // 設(shè)置畫筆顏色
    UIColor.blue.setStroke();
        
    path.fill();
    path.stroke();
}

測試結(jié)果:

6

七、檢索顏色信息

// 獲取與此UIColor相對應(yīng)的Quartz顏色
open var cgColor: CGColor { get }

// 獲取與此UIColor相對應(yīng)的Core Image封裝的顏色
@available(iOS 5.0, *)
open var ciColor: CIColor { get }

// 獲取灰度顏色空間中組成顏色的灰度分量   
@available(iOS 5.0, *)
open func getWhite(_ white: UnsafeMutablePointer<CGFloat>?, alpha: UnsafeMutablePointer<CGFloat>?) -> Bool

// 獲取HSB顏色空間中組成顏色的組件
@available(iOS 5.0, *)
open func getHue(_ hue: UnsafeMutablePointer<CGFloat>?, saturation: UnsafeMutablePointer<CGFloat>?, brightness: UnsafeMutablePointer<CGFloat>?, alpha: UnsafeMutablePointer<CGFloat>?) -> Bool

// 獲取RGB顏色空間中組成顏色的組件
@available(iOS 5.0, *)
open func getRed(_ red: UnsafeMutablePointer<CGFloat>?, green: UnsafeMutablePointer<CGFloat>?, blue: UnsafeMutablePointer<CGFloat>?, alpha: UnsafeMutablePointer<CGFloat>?) -> Bool

測試代碼如下:

// 測試獲取color的相關(guān)信息
func testGetInfomationWithColor() {
        
    var r: CGFloat = 0;
    var g: CGFloat = 0;
    var b: CGFloat = 0;
    var a: CGFloat = 0;
        
    UIColor.red.getRed(&r, green: &g, blue: &b, alpha: &a);
    print("RGB分量---" + "r:" + String(describing: r) + " g:" + String(describing: g) + " b:" + String(describing: b) + " a:" + String(describing: a));
        
    var hh: CGFloat = 0;
    var ss: CGFloat = 0;
    var bb: CGFloat = 0;
    var aa: CGFloat = 0;
        
    UIColor.red.getHue(&hh, saturation: &ss, brightness: &bb, alpha: &aa);
        
    print("HSB分量---" + "hh:" + String(describing: hh) + " ss:" + String(describing: ss) + " bb:" + String(describing: bb) + " aa:" + String(describing: aa));

    var www: CGFloat = 0;
    var aaa: CGFloat = 0;
        
    UIColor.red.getWhite(&www, alpha: &aaa);
        
    print("灰度分量---" + "www:" + String(describing: www) + " aaa:" + String(describing: aaa));

    print("cgcolor---" + String(describing: UIColor.red.cgColor));
        
    print("cicolor---" + String(describing: UIColor.init(ciColor: CIColor.red()).ciColor));
    }

測試結(jié)果:

RGB分量---r:1.0 g:0.0 b:0.0 a:1.0
HSB分量---hh:0.0 ss:1.0 bb:1.0 aa:1.0
灰度分量---www:0.509023487567902 aaa:1.0
cgcolor---<CGColor 0x6100000aa680> [<CGColorSpace 0x61000002f940> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1; extended range)] ( 1 0 0 1 )
cicolor---(1 0 0 1)

注意:UIColor的CGColor總是有效的,不管它是通過CGColor,CIColor,還是其他方法創(chuàng)建的,CGColor屬性都總是有效的;但是CIColor屬性就不總是有效的,只有當(dāng)UIColor是通過CIColor創(chuàng)建的時(shí)候,他才是有效的,否則訪問該屬性將會(huì)拋出異常

八、Color Literal

// 字面量顏色 不要直接調(diào)用
@nonobjc required public convenience init(colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float)

這個(gè)API,是Xcode提供的一個(gè)可視化顏色選擇器,不需要直接調(diào)用,使用方法如下:

1、設(shè)置顏色的時(shí)候輸入 color literal 會(huì)有智能提示如下:

2、回車后,會(huì)出現(xiàn)顏色選擇界面

3、可以選擇一個(gè)想要的顏色,還可以點(diǎn)擊下方的 Other ,選顏色蠟筆或者直接輸入顏色值。選完后在代碼里就會(huì)有個(gè)小方塊。里面填充的就是剛剛選的顏色,如下:


4、運(yùn)行后結(jié)果如下:

5、實(shí)質(zhì)上,小方塊就是這個(gè)API的替代顯示,復(fù)制整個(gè)函數(shù)代碼粘貼如下:

// 測試字面量初始化方法
func testLiteralInit() {
        
    self.addImageView(color: #colorLiteral(red: 0.1215686277, green: 0.01176470611, blue: 0.4235294163, alpha: 1));
}

九、完畢

UIColor 這個(gè)類測試講解到這里就結(jié)束了,在之后的時(shí)間里,我會(huì)將swift下的相關(guān)類依次整理一下,溫故而知新!

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

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,151評(píng)論 4 61
  • UIColor,CGColor,CIColor三者的區(qū)別和聯(lián)系 最近看了看CoreGraphics的東西,看到關(guān)于...
    VincentHK閱讀 1,640評(píng)論 0 3
  • 某日我去工地檢驗(yàn)橋梁基樁鋼筋籠,間距太大,怒而拒驗(yàn)。施工隊(duì)死纏活繞,笑而不理,下午四時(shí)土方施工員老張打來電話:我拉...
    騎手為什么歌唱草原閱讀 547評(píng)論 0 1
  • 矛盾說:寒風(fēng)和冰雪的天氣能殺人,但也刺激人們活動(dòng)起來奮斗。霧,能使你苦悶,使你頹唐闌珊,像陷在爛泥淖中,滿心想掙扎...
    盤耕閱讀 165評(píng)論 0 0
  • 08 我們終究逃不過分離 從小學(xué)到大學(xué),我們經(jīng)歷無數(shù)個(gè)分離。與許多的人從陌生到熟悉,由熟悉到陌生,然后徹底淡出彼此...
    穆念晴閱讀 410評(píng)論 10 6