Цветовая модель
UIKit предоставляет чрезвычайно неудобные методы для покомпонентной работы с цветом. Такие вещи, как изменение яркости или перевод в градации серого требуют слишком много действий.
Чтобы упростить процесс, мной был создан класс ColorModel, позволяющий управлять основными компонентами цвета в максимально понятном виде — через свойства. Вдобавок корректируются ситуации обнуления оттенка и насыщенности.
import UIKit
/**
The `ColorModel` class provides simple mechanism for modeling color by components.
*/
class ColorModel {
// MARK: - Properties
/**
The internal flag to prevent loops: changing the components
changes color and brings components updating.
*/
private var needsUpdateColor = true
/**
The `UIColor` associated with the model.
*/
var color: UIColor! {
didSet {
updateComponents()
}
}
// MARK: RGB
/**
The red component. Value between 0.0 and 1.0.
*/
var red = CGFloat() {
didSet {
if needsUpdateColor {
color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
}
}
}
/**
The green component. Value between 0.0 and 1.0.
*/
var green = CGFloat() {
didSet {
if needsUpdateColor {
color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
}
}
}
/**
The blue component. Value between 0.0 and 1.0.
*/
var blue = CGFloat() {
didSet {
if needsUpdateColor {
color = UIColor(red: red, green: green, blue: blue, alpha: alpha)
}
}
}
// MARK: HSB
/**
The hue component. Value between 0.0 and 1.0.
*/
var hue = CGFloat() {
didSet {
if needsUpdateColor {
color = UIColor(hue: hue,
saturation: saturation,
brightness: brightness,
alpha: alpha)
}
}
}
/**
The saturation component. Value between 0.0 and 1.0.
*/
var saturation = CGFloat() {
didSet {
if needsUpdateColor {
color = UIColor(hue: hue,
saturation: saturation,
brightness: brightness,
alpha: alpha)
}
}
}
/**
The brightness component. Value between 0.0 and 1.0.
*/
var brightness = CGFloat() {
didSet {
if needsUpdateColor {
color = UIColor(hue: hue,
saturation: saturation,
brightness: brightness,
alpha: alpha)
}
}
}
// MARK: Grayscale
/**
The grayscale component. Value between 0.0 and 1.0.
*/
var white = CGFloat() {
didSet {
if needsUpdateColor {
color = UIColor(white: white, alpha: alpha)
}
}
}
/**
The opacity component. Value between 0.0 and 1.0.
*/
var alpha = CGFloat() {
didSet {
if needsUpdateColor {
color = color.colorWithAlphaComponent(alpha)
}
}
}
// MARK: - Initialization
init(color: UIColor) {
self.color = color
updateComponents()
}
// MARK: - Main
/**
Updates the color components.
*/
private func updateComponents() {
var newHue = CGFloat()
var newSaturation = CGFloat()
var newBrightness = CGFloat()
needsUpdateColor = false
color.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
color.getWhite(&white, alpha: nil)
color.getHue(&newHue,
saturation: &newSaturation,
brightness: &newBrightness,
alpha: nil)
// Handling the reset hue to 0 when the brightness and saturation are set to 0
if newBrightness != 0 && newSaturation != 0 {
hue = newHue
}
// Handling the reset saturation to 0 when the brightness is set to 0
if newBrightness != 0 {
saturation = newSaturation
}
brightness = newBrightness
needsUpdateColor = true
}
}