Search code examples
swiftuikituicolorrgba

Swift - UIColor.black crashes app when converting from UIColor to string


The code below works fine with UIColor.Purple or UIColor.Yellow for example but the app crashes when I use UIColor.black.

Fatal error: Index out of range it seems like components[2] and [3] do not exists when UIColor.black is used. I know i am force unwrapping but shouldn't all colours have RGBA?

//UIColor RGBA to string
public extension UIColor {

class func StringFromUIColor(color: UIColor) -> String{
    let components = color.cgColor.components
    return "[\(components![0]), \(components![1]), \(components![2]), \(components![3])]"
}

class func UIColorFromString(string: String) -> UIColor {
    let componentsStringStepOne = string.replacingOccurrences(of: "[", with: "")
    let componentsString = componentsStringStepOne.replacingOccurrences(of: "]", with: "")
    let components = componentsString.components(separatedBy: ", ")
    return UIColor(red: CGFloat((components[0] as NSString).floatValue), green: CGFloat((components[1] as NSString).floatValue), blue: CGFloat((components[2] as NSString).floatValue), alpha: CGFloat((components[3] as NSString).floatValue))
}

}

also is there a better way to write this part of the code?

let componentsStringStepOne = string.replacingOccurrences(of: "[", with: "")
    let componentsString = componentsStringStepOne.replacingOccurrences(of: "]", with: "")
    let components = componentsString.components(separatedBy: ", ")

Any helps is appreciated! Thanks.


Solution

  • This is the solution I came up with following rmaddy and kamran response. It's not crashing the app and I am getting the right colours. It's saving in the plist how I want it to look whether it is black or a colour eg. [0.2,0.4,0.5,1.0]. Thanks for the help

    public extension UIColor {
    
    class func StringFromUIColor(color: UIColor) -> String{
        let components = color.cgColor.components
        if components?.count == 2 {
             return "[\(components![0]), \(components![0]), \(components![0]), \(components![1])]"
        } else {
            return "[\(components![0]), \(components![1]), \(components![2]), \(components![3])]"
        }
    }
    
    class func UIColorFromString(string: String) -> UIColor {
        let componentsStringStepOne = string.replacingOccurrences(of: "[", with: "")
        let componentsString = componentsStringStepOne.replacingOccurrences(of: "]", with: "")
        let components = componentsString.components(separatedBy: ", ")
        if components.count == 2 {
            return UIColor(white: CGFloat((components[0] as NSString).floatValue), alpha: CGFloat((components[1] as NSString).floatValue))
        } else {
              return UIColor(red: CGFloat((components[0] as NSString).floatValue), green: CGFloat((components[1] as NSString).floatValue), blue: CGFloat((components[2] as NSString).floatValue), alpha: CGFloat((components[3] as NSString).floatValue))
        }
      }
    }