-
Notifications
You must be signed in to change notification settings - Fork 13
/
UIColorExtensions.swift
120 lines (96 loc) · 3.93 KB
/
UIColorExtensions.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import UIKit
public extension UIColor {
/**
Initialize color from hex int (eg. 0xff00ff).
- parameter hex: Hex int to create color from
*/
convenience init(hex: UInt32) {
self.init(
red: CGFloat(Double((hex & 0xFF0000) >> 16) / 255.0),
green: CGFloat(Double((hex & 0xFF00) >> 8) / 255.0),
blue: CGFloat(Double(hex & 0xFF) / 255.0),
alpha: 1.0
)
}
/**
Initialize color from hex string (eg. "#ff00ff"). Leading '#' is mandatory.
- parameter hexString: Hex string to create color from
*/
convenience init(hexString: String) {
var rgbValue: UInt32 = 0
let scanner = Scanner(string: hexString)
scanner.scanLocation = 1 // bypass '#' character
scanner.scanHexInt32(&rgbValue)
self.init(hex: rgbValue)
}
/**
Returns color as hex string (eg. '#ff00ff') or nil if RGBA components coudn't be loaded.
Monochrome check included (works for white/black/clear).
*/
var hexString: String? {
guard let components = cgColor.components, cgColor.numberOfComponents > 1 else { return nil }
let isMonochrome = cgColor.colorSpace?.model == .monochrome
let r: CGFloat = isMonochrome ? components[0] : components[0]
let g: CGFloat = isMonochrome ? components[0] : components[1]
let b: CGFloat = isMonochrome ? components[0] : components[2]
return String(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)), lroundf(Float(b * 255)))
}
/// Create random color
static func random() -> UIColor {
let randomRed = CGFloat(arc4random()) / CGFloat(UInt32.max)
let randomGreen = CGFloat(arc4random()) / CGFloat(UInt32.max)
let randomBlue = CGFloat(arc4random()) / CGFloat(UInt32.max)
return UIColor(red: randomRed, green: randomGreen, blue: randomBlue, alpha: 1.0)
}
/**
Make color lighter with defined amount.
- parameter amount: Defines how much lighter color is returned. Should be from 0.0 to 1.0
*/
func brightened(by amount: CGFloat = 0.25) -> UIColor {
return with(brightnessAmount: 1 + max(0, amount))
}
/**
Make color darker with defined amount.
- parameter amount: Defines how much darker color is returned. Should be from 0.0 to 1.0
*/
func darkened(by amount: CGFloat = 0.25) -> UIColor {
return with(brightnessAmount: 1 - max(0, amount))
}
fileprivate func with(brightnessAmount: CGFloat) -> UIColor {
var h: CGFloat = 0
var s: CGFloat = 0
var b: CGFloat = 0
var a: CGFloat = 0
guard getHue(&h, saturation: &s, brightness: &b, alpha: &a) else { return self }
return UIColor(
hue: h,
saturation: s,
brightness: b * brightnessAmount,
alpha: a
)
}
/// Returns true for light colors. When light color is used as background, you should use black as a text color.
var isLight: Bool {
let components = self.cgColor.components
let red = components?[0]
let green = components?[1]
let blue = components?[2]
let brightness = (red! * 299 + green! * 587 + blue! * 114) / 1000
return brightness > 0.5
}
/// Returns true for dark colors. When dark color is used as background, you should use white as a text color.
var isDark: Bool {
return !isLight
}
/// Create image from color with defined size.
func image(of size: CGSize = CGSize(width: 1, height: 1)) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(self.cgColor)
context?.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
}