artemkrachulov
7/23/2016 - 10:03 AM

UIColor+HEX.swift

//
//  UIColor+HEX.swift
//
//  Created by Artem Krachulov
//  Copyright (c) 2016 Artem Krachulov. All rights reserved.
//	http://www.artemkrachulov.com
//

import UIKit

//  MARK: - HEX

extension UIColor {
  
  /// Return hex representation of UIColor object.
  ///
  /// Usage:
  ///
  ///		UIColor(red: 1, green: 0.5, blue: 0.8, alpha: 0.5).hex // "#FF7FCC7F"
  ///		UIColor.whiteColor().hex // "#FFFFFFFF"
  ///		UIColor.blackColor().hex // "#000000FF"
  public var hex: String {
    
    let rgbaComponents = CGColorGetComponents(CGColor)
    
    var hex = "#"
    
    for index in 0...3 {
      var index = index
      
      if CGColorGetNumberOfComponents(CGColor) == 2 {
        index = index == 3 ? 1 : 0
      }
      
      hex += String(format:"%0.2X", UInt8(rgbaComponents[index] * 255))
    }
    return hex
  }
  
  /// Initializing UIColor object from string HEX value
  /// Supported single and multiple HEX character in lowercase or uppercase mode
  ///
  /// Usage:
  ///
  ///		UIColor.fromHex("#FC9") // UIColor(red: 1, green: 0.8, blue: 0.6, alpha: 1)
  ///		UIColor.fromHex("#FFCC99") // UIColor(red: 1, green: 0.8, blue: 0.6, alpha: 1)
  ///		UIColor.fromHex("#FC93") // UIColor(red: 1, green: 0.8, blue: 0.6, alpha: 0.2)
  ///		UIColor.fromHex("#FFCC9933")) // UIColor(red: 1, green: 0.8, blue: 0.6, alpha: 0.2)
  class public func fromHex(hex: String) -> UIColor! {
    
    let hex = hex.lowercaseString
    
    let hexCharSet = NSCharacterSet(charactersInString: "#0123456789abcdef")
    
    if hex.rangeOfCharacterFromSet(hexCharSet.invertedSet, options: .CaseInsensitiveSearch) != nil {
      
      print("Error: Unknown character in HEX string \(hex)")
      
    } else {
      if hex.substringToIndex(hex.startIndex.advancedBy(1)) == "#" {
        
        let hexLength = hex.characters.count
        
        if hexLength < 4 || hexLength == 6 || hexLength == 8 || hexLength > 9  {
          
          print("Error: Unknown HEX length \(hex)")
          
        } else {
          
          var red: CGFloat = 255
          var green: CGFloat = 255
          var blue: CGFloat = 255
          var alpha: CGFloat = 255
          
          // Range for paired or unpaired hex chars
          let range = hexLength == 5 || hexLength == 9 ? 3 : 2
          
          // Multiplyer if we need duplicate hex char
          let multiply = hexLength == 4 || hexLength == 5 ? 1 : 2
          
          for index in 0...range {
            
            var hexChar = hex.substringWithRange(hex.startIndex.advancedBy(multiply * index + 1) ..< hex.startIndex.advancedBy(multiply * index + 1 + multiply))
            
            // Duplicate char
            if multiply == 1 {
              hexChar += hexChar
            }
            
            let value = CGFloat(strtoul(hexChar, nil, 16))
            
            switch index {
            case 0: red = value
            case 1: green = value
            case 2: blue = value
            case 3: alpha = value
            default: ()
            }
          }
          
          return UIColor(red: red / 255, green: green / 255, blue: blue / 255, alpha: alpha / 255)
        }
      } else {
        print("Error: HEX without \"#\"")
      }
    }
    
    return nil
  }
  
  /// Initializing UIColor object from string HEX value and non-hex alpha component.
  /// Supported single and multiple HEX character in lowercase or uppercase mode
  ///
  /// Usage:
  ///
  ///		UIColor.fromHex("#FC9", alpha: 1) // UIColor(red: 1, green: 0.8, blue: 0.6, alpha: 1)
  ///		UIColor.fromHex("#FFCC99", alpha: 1.0) // UIColor(red: 1, green: 0.8, blue: 0.6, alpha: 1)
  class public func fromHex(hex: String, alpha: CGFloat) -> UIColor! {
    
    var hex = hex
    
    if hex.characters.count == 4 {
      
      var _hex = "#"
      for index in 0..<3 {
        let hexChar = hex.substringWithRange(hex.startIndex.advancedBy(index + 1) ..< hex.startIndex.advancedBy(index + 2))
        
        _hex += hexChar + hexChar
      }
      
      hex = _hex
    }
    return fromHex(hex + String(format:"%0.2X", UInt8(alpha*255)))
  }
}