Цветовая модель

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
    }
}

Скачать ColorModel.zip