玩转swift -- UIKit 之 UIColor

前言

UIColor类是UIKit中用来存储颜色数据的一个类,想要清晰的了解这个类中的相关属性、方法,则需要先了解一个名词:颜色空间

不同的设备处理颜色的方式是不同的, 每个设备都有他所支持的颜色范围, 在一个设备上产生的颜色可能在另一台设备上无法提供.所以,不同的设备就可能会具有不同的颜色空间,去解析相应的颜色数据(比如UIColor)。

特别的,在iOS系统中,必须使用设备颜色空间(device color space)

在iOS 10之前的iOS版本上,以及在iOS 10之前的iOS版本上链接的应用程序,可以在两个颜色空间之一中创建和返回颜色:

Device-Dependent Gray
Device-Dependent RGB

iOS 10之后或之后连接,并且在iOS 10或更高版本上运行,则颜色将在扩展颜色空间中创建:

kCGColorSpaceExtendedGray
kCGColorSpaceExtendedSRGB

CoreGraphics中有个CGColorSpace类, 这个类可以用来获取不同的设备颜色空间,举例(三个比较常见的颜色空间)如下:

// 一个device-dependent 灰度颜色空间
@available(iOS 2.0, *)
public func CGColorSpaceCreateDeviceGray() -> CGColorSpace
// 一个device-dependent RGB颜色空间
@available(iOS 2.0, *)
public func CGColorSpaceCreateDeviceRGB() -> CGColorSpace
//  一个device-dependent CMYK颜色空间
@available(iOS 2.0, *)
public func CGColorSpaceCreateDeviceCMYK() -> CGColorSpace

然后还要了解的是 UIColor、CGColor、CIColor 之间的关系及转化,本篇文章主要讲 UIColor 的相关知识,这篇文章对于三者之间的关系讲的很详尽,自己就不重复造轮子了,假如你理解了颜色空间与颜色数据之间的关系,那么这篇文章也就很好理解了。

进入正题(基于iOS 10)

一、创建系统颜色

extension UIColor {
    // 在浅色背景上显示文本的系统颜色。
    open class var lightText: UIColor { get } 
    // 在深色背景上显示文本的系统颜色。
    open class var darkText: UIColor { get } 
    // 分组表的背景的系统颜色。
    open class var groupTableViewBackground: UIColor { get }
}

测试代码如下:

// 测试创建系统颜色
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;
}

结果如下:

UIExtendedGrayColorSpace 0 1
UIExtendedGrayColorSpace 1 0.6
UIExtendedSRGBColorSpace 0.937255 0.937255 0.956863 1

1

二、使用预定义颜色创建颜色对象

// 黑色
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 } 
// 蓝色
open class var blue: UIColor { get } 
// 蓝绿色
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 } 

测试代码如下:

// 测试使用预定义颜色创建颜色对象
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);
}

测试结果如下

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

三、在特定颜色空间中创建自定义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)

测试代码如下:

// 测试在特定颜色空间创建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));
}

结果如下:

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后,通过图形堆栈扩展这种方式比以往支持广色域的显示设备更加容易。现在对UIKit扩展可以在sRGB的色彩空间下工作,性能更好,也可以在更广泛的色域来搭配sRGB颜色。

四、以现有的颜色数据创建UIColor对象

// 由指定的Quartz颜色生成一个UIcolor对象
public init(cgColor: CGColor)
// 由指定的Core Image颜色生成一个UIcolor对象
@available(iOS 5.0, *)
public init(ciColor: CIColor)
// 创建并返回一个与原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));
}

测试结果如下:

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

五、由Image转为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);
}

测试结果如下:

kCGColorSpaceModelPattern 1 

5

建议:在实际项目中尽量避免使用这种方式加载加图片,因为这种加载方式会比直接加载图片占用更大的内存。

六、设置图形上下文的绘图颜色

// 同时设置画笔颜色和填充颜色
open func set()
// 设置填充颜色
open func setFill()
// 设置画笔颜色
open func setStroke()

测试代码如下:

// 测试设置图形上下文的绘图颜色
func testDrawColor() {
        
    let pathView = PathView.init(frame: self.view.bounds);
    self.view.addSubview(pathView);
}

PathView.swift内:

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;
    // 设置填充颜色    
    UIColor.red.setFill();
    // 设置画笔颜色
    UIColor.blue.setStroke();
        
    path.fill();
    path.stroke();
}

测试结果:

6

七、检索颜色信息

// 获取与此UIColor相对应的Quartz颜色
open var cgColor: CGColor { get }

// 获取与此UIColor相对应的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的相关信息
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));
    }

测试结果:

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,还是其他方法创建的,CGColor属性都总是有效的;但是CIColor属性就不总是有效的,只有当UIColor是通过CIColor创建的时候,他才是有效的,否则访问该属性将会抛出异常

八、Color Literal

// 字面量颜色 不要直接调用
@nonobjc required public convenience init(colorLiteralRed red: Float, green: Float, blue: Float, alpha: Float)

这个API,是Xcode提供的一个可视化颜色选择器,不需要直接调用,使用方法如下:

1、设置颜色的时候输入 color literal 会有智能提示如下:

2、回车后,会出现颜色选择界面

3、可以选择一个想要的颜色,还可以点击下方的 Other ,选颜色蜡笔或者直接输入颜色值。选完后在代码里就会有个小方块。里面填充的就是刚刚选的颜色,如下:


4、运行后结果如下:

5、实质上,小方块就是这个API的替代显示,复制整个函数代码粘贴如下:

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

九、完毕

UIColor 这个类测试讲解到这里就结束了,在之后的时间里,我会将swift下的相关类依次整理一下,温故而知新!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,943评论 4 60
  • UIColor,CGColor,CIColor三者的区别和联系 最近看了看CoreGraphics的东西,看到关于...
    VincentHK阅读 1,599评论 0 3
  • 某日我去工地检验桥梁基桩钢筋笼,间距太大,怒而拒验。施工队死缠活绕,笑而不理,下午四时土方施工员老张打来电话:我拉...
    骑手为什么歌唱草原阅读 524评论 0 1
  • 矛盾说:寒风和冰雪的天气能杀人,但也刺激人们活动起来奋斗。雾,能使你苦闷,使你颓唐阑珊,像陷在烂泥淖中,满心想挣扎...
    盘耕阅读 147评论 0 0
  • 08 我们终究逃不过分离 从小学到大学,我们经历无数个分离。与许多的人从陌生到熟悉,由熟悉到陌生,然后彻底淡出彼此...
    如画的生活阅读 388评论 10 6