Nurgling96
Nurgling96

Reputation: 576

How to create a UIColor from a String like "rgb(0,0,0)"?

I have a string from server in a format like "rgb(0,0,0)", which should be used on some UI elements.

The main problem is the various colours like "rgb(20,120,4)" etc.

Is there a way to parse it in something like UIColor(red: 0, green: 0, blue: 0, alpha: 1)?

Upvotes: 0

Views: 795

Answers (3)

Martin R
Martin R

Reputation: 539745

There are so many possible solutions! Here is one using NSScanner:

extension UIColor {
    convenience init?(rgbString : String) {
        var red = 0.0
        var green = 0.0
        var blue = 0.0
        
        let scanner = NSScanner(string : rgbString)
        guard scanner.scanString("rgb(", intoString: nil)
            && scanner.scanDouble(&red)
            && scanner.scanString(",", intoString: nil)
            && scanner.scanDouble(&green)
            && scanner.scanString(",", intoString: nil)
            && scanner.scanDouble(&blue)
            && scanner.scanString(")", intoString: nil) else {
                return nil
        }
        self.init(red: CGFloat(red/255.0), green: CGFloat(green/255.0), blue: CGFloat(blue/255.0), alpha: 1.0)
    }
}

Usage example:

if let col = UIColor(rgbString: "rgb(20,120.5, 4)") {
    print(col)
} else {
    print("invalid color specification")
}

Update for Swift 3/4:

extension UIColor {
    convenience init?(rgbString: String) {
        var red = 0.0
        var green = 0.0
        var blue = 0.0
        
        let scanner = Scanner(string: rgbString)
        guard scanner.scanString("rgb(", into: nil)
            && scanner.scanDouble(&red)
            && scanner.scanString(",", into: nil)
            && scanner.scanDouble(&green)
            && scanner.scanString(",", into: nil)
            && scanner.scanDouble(&blue)
            && scanner.scanString(")", into: nil) else {
                return nil
        }
        self.init(red: CGFloat(red/255.0), green: CGFloat(green/255.0), blue: CGFloat(blue/255.0), alpha: 1.0)
    }
}

Update for Swift 5:

extension UIColor {
    convenience init?(rgbString: String) {

        let scanner = Scanner(string: rgbString)
        guard scanner.scanString("rgb(") != nil,
              let red = scanner.scanDouble(),
              scanner.scanString(",") != nil,
              let green = scanner.scanDouble(),
              scanner.scanString(",") != nil,
              let blue = scanner.scanDouble(),
              scanner.scanString(")") != nil else {
                return nil
        }
        self.init(red: CGFloat(red/255.0), green: CGFloat(green/255.0), blue: CGFloat(blue/255.0), alpha: 1.0)
    }
}

Upvotes: 7

Twitter khuong291
Twitter khuong291

Reputation: 11672

You can try this.

import UIKit

let string1 = "rgb(25.00,100.0,100)"

let indexToRemoveTheLast = string1.endIndex.advancedBy(-1)
let substring1 = string1.substringToIndex(indexToRemoveTheLast)
let indexToRemoveTheFirst = string1.startIndex.advancedBy(4)
let substring2 = substring1.substringFromIndex(indexToRemoveTheFirst)

var colorsString = substring2.characters.split{$0 == ","}.map(String.init)
let red = (Float(colorsString[0])!) / 255
let green = (Float(colorsString[1])!) / 255
let blue = (Float(colorsString[2])!) / 255

let myColor = UIColor(red: CGFloat(red), green: CGFloat(green), blue: CGFloat(blue), alpha: 1)

the result here:

enter image description here

Upvotes: 1

OgreSwamp
OgreSwamp

Reputation: 4692

Here is a method which will convert your string to the UIColor. Possibly there is even better solution with regex, but I'm pretty bad in regex.

func colorFromString(colorString: String) -> UIColor? {
    // strip down rgb and parenthesis
    let combinedCharacterSet = NSMutableCharacterSet.letterCharacterSet()
    combinedCharacterSet.addCharactersInString("()")

    let trimmedString = colorString.stringByTrimmingCharactersInSet(combinedCharacterSet)
    let rgbValueStrings = trimmedString.componentsSeparatedByString(",")

    if rgbValueStrings.count != 3 {
        return nil
    }

    if let r =  Double(rgbValueStrings[0]) where r >= 0 && r <= 255,
        let g =  Double(rgbValueStrings[1]) where g >= 0 && g <= 255,
        let b =  Double(rgbValueStrings[2]) where b >= 0 && b <= 255 {
        return UIColor(red: CGFloat(r/255), green: CGFloat(g/255), blue: CGFloat(b/255), alpha: 1.0)
    } else {
        return nil
    }
}

and playground can be downloaded here

Upvotes: 2

Related Questions