【问题标题】:How to create a UIColor from a String like "rgb(0,0,0)"?如何从“rgb(0,0,0)”之类的字符串创建 UIColor?
【发布时间】:2016-04-04 16:04:33
【问题描述】:

我有一个来自服务器的字符串,格式类似于“rgb(0,0,0)”,应该用于某些 UI 元素。

主要问题是各种颜色,如“rgb(20,120,4)”等。

有没有办法以UIColor(red: 0, green: 0, blue: 0, alpha: 1) 之类的方式解析它?

【问题讨论】:

  • 服务器返回码是什么格式的?细绳?请发布更多代码,以便我可以帮助您
  • 我只想去掉第一个字符,但这不是很好,我可以告诉你怎么做吗?
  • “有没有办法解析它” 是的,有(虽然我不太明白你将如何获得 alpha 信息,因为你没有 alpha 信息开始)。

标签: ios swift parsing uicolor


【解决方案1】:

有很多可能的解决方案!这是一个使用 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)
    }
}

使用示例:

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

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

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

【讨论】:

    【解决方案2】:

    这是一种将您的字符串转换为UIColor 的方法。正则表达式可能有更好的解决方案,但我的正则表达式很糟糕。

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

    游乐场可以是downloaded here

    【讨论】:

    • 您可能还想在拆分为单个字符串后修剪空格字符,因为数字周围的空格将无法正确解析。
    【解决方案3】:

    你可以试试这个。

    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)
    

    这里的结果:

    【讨论】:

    • 使用扩展的不错的解决方案!
    • 该代码不起作用。 Int 是颜色构造函数的错误类型,如果颜色代码超过 1 位或收到格式错误的字符串,它将失败
    • 您没有解决我指出的第二个问题(UIColor 初始化程序的 rgb 值需要除以 255 介于 0 和 1 之间)
    • 用“rgb(10,0,10)”和“rgb(255,0,255)”试试你的代码。它们都将产生相同的颜色,因为UIColor(red:green:blue:alpha:) 期望值介于 0-1 之间,任何大于 1 的值都被视为传入 1。
    • 你的代码有各种各样的问题:你打开包装做得更糟。你不应该。你不检查数字范围,你根本不检查它是否是数字。最后,正如@dan 指出的那样,您不会将结果除以 255。
    猜你喜欢
    • 2010-12-27
    • 2010-10-01
    • 2017-11-30
    • 2011-03-01
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 2020-07-30
    相关资源
    最近更新 更多