我该如何从十六进制字符串创建UIColor?

584

我该如何从十六进制字符串格式(例如#00FF00)创建一个UIColor呢?


Erica还为iOS和OSX开发了一个出色的颜色扩展类别 - Echilon
这是另一个库:https://github.com/burhanuddin353/TFTColor - Burhanuddin Sunelwala
50个回答

1

Swift版本:

extension UIColor {
    convenience init?(var hex: String) {
        hex = hex.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).uppercaseString
        hex = (hex.hasPrefix("#")) ? hex.substringFromIndex(advance(hex.startIndex, 1)) : hex

        var value: UInt32 = 0
        if NSScanner(string: hex).scanHexInt(&value) {
            if count(hex) == 8 {
                self.init(red: CGFloat((value & 0xFF000000) >> 24) / 255.0,
                    green: CGFloat((value & 0x00FF0000) >> 16) / 255.0,
                    blue: CGFloat((value & 0x0000FF00) >> 8) / 255.0,
                    alpha: CGFloat((value & 0x000000FF)) / 255.0)
                return
            } else if count(hex) == 6 {
                self.init(red: CGFloat((value & 0xFF0000) >> 16) / 255.0,
                    green: CGFloat((value & 0x00FF00) >> 8) / 255.0,
                    blue: CGFloat(value & 0x0000FF) / 255.0,
                    alpha: 1.0)
                return
            }
        }
        self.init()
        return nil
    }
}

1

1

Swift 3 示例 Ethan Strider的答案。一个接受十六进制字符串并返回UIColor的函数。
(您可以使用以下任何格式输入十六进制字符串:#ffffffffffff

示例:

func hexStringToUIColor (hex:String) -> UIColor {
    var cString: String = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()

    if (cString.hasPrefix("#")) {
        if let range = cString.range(of: cString) {
            cString = cString.substring(from: cString.index(range.lowerBound, offsetBy: 1))
        }
    }

    if ((cString.characters.count) != 6) {
        return UIColor.gray
    }

    var rgbValue: UInt32 = 0
    Scanner(string: cString).scanHexInt32(&rgbValue)

    return UIColor(
        red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
        green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
        blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
        alpha: CGFloat(1.0)
    )
}

使用方法:

var color1 = hexStringToUIColor("#d3d3d3")

1

优化自@Tom的原始答案,随意在这里更新代码。

extension UIColor{
    convenience init (hexString:String) {
        var cleanString:String = hexString.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).uppercaseString

        if (cleanString.hasPrefix("#")) {
            cleanString = cleanString.substringFromIndex(cleanString.startIndex.advancedBy(1))
        }

        if (cleanString.characters.count != 6) {
            self.init()
        }
        else{
            var rgbValue = UInt32()
            let scanner = NSScanner(string: cleanString)
            scanner.scanHexInt(&rgbValue)

            self.init(
                red: CGFloat((rgbValue & 0xFF0000) >> 16)/255.0,
                green: CGFloat((rgbValue & 0xFF00) >> 8)/255.0,
                blue: CGFloat(rgbValue & 0xFF)/255.0,
                alpha: 1.0)
        }
    }
}

这很不错,但我认为它真的需要返回一个可选的UIColor,并检查scanHexInt是否失败(返回布尔值)。如果我传入一个HexString,我不确定是否想要得到一些奇怪定义的UIColor,可能只调用了.init()而没有实际值! - Kendall Helmstetter Gelner

1
我为大家推荐一个刚刚发现的网站,它可以完成所有的脏活累活,并且从HEX或RGB开始,在ObjC、Swift和Xamarin中输出代码。

https://www.uicolor.xyz/#/hex-to-ui


0
在Swift中,我创建了一个类扩展,其中包含以下方法,用于将十六进制代码转换为UIColor。
extension UIColor {  
  convenience init(R: CGFloat, G: CGFloat, B: CGFloat, alpha: CGFloat) {
    self.init(red: R/255.0, green: G/255.0, blue: B/255.0, alpha: alpha)
  }

  class func colorWithHex(hex: UInt, alpha: CGFloat) -> UIColor {
    return UIColor(R: CGFloat((hex & 0xFF0000) >> 16), G: CGFloat((hex & 0x00FF00) >> 8), B: CGFloat(hex & 0x0000FF), alpha: alpha)
  }
}

0

几种解决方案中涉及了一些不必要使用的NSString。这个UIColor类的扩展更简单、更快:

+ colorWithHex:(UInt32)hex alpha:(CGFloat)alpha
{
    return [UIColor colorWithRed:((hex & 0xFF0000) >> 16)/255.0
                           green:((hex & 0x00FF00) >> 8)/255.0
                            blue:( hex & 0x0000FF)/255.0
                           alpha:alpha];
}

并且只需简单地使用它:

return [UIColor colorWithHex:0x006400 alpha:1.0]; // HTML darkgreen

不带评论的负评对任何人都没有帮助,因此,如果您(匿名)反对我特别使用NSString,请注意,在这个问题中,远远超过排名第一的答案,由Tom提供了同样的解决方案。在我看来,UIColor类扩展只是比#define更干净的解决方案。我能想到的唯一可能需要将十六进制颜色代码转换为NSString的原因是,如果您正在尝试解析HTML流,那么此时您应该研究使用NSAttributedString进行init并使用NSHTMLTextDocumentType,并让它处理*所有标记。 - tiritea

0

大多数答案使用 Scanner、位掩码或子字符串操作。

还可以使用 chunks(ofCount:)UInt8.init(_:radix:) 提取颜色组件:

import Foundation
import XCTest
import Algorithms

class UIColorFromStringTests: XCTestCase {
    func testUIColorFromString() throws {
        let color = "00FF00"
        let components = color
            .chunks(ofCount: 2)
            .compactMap { UInt8($0, radix: 16) }
        XCTAssertEqual(components, [0x00, 0xFF, 0x00])
        let red = CGFloat(components[0]) / 255 // 0
        let green = CGFloat(components[1]) / 255 // 1
        let blue = CGFloat(components[2]) / 255 // 0
        _ = UIColor(red: red, green: green, blue: blue, alpha: 1)
    }
}

0

这里有一个很好的UIColor类别,其中包含许多功能。

用法:

textView.textColor = [UIColor colorWithHexString:textColorHex];
NSLog(@"Text Color Hex: %@", textColorHex);

textColorHex的格式为@"FFFFFF",不带#符号。


0
使用Xcode的本地Color Literals功能轻松添加十六进制颜色。
在您的代码中键入Color Literal,然后让Xcode自动完成其余部分。
颜色选择器UI将允许您粘贴十六进制颜色:#FF9300

color picker

宏的 git diff 将显示 RGB 值而不是十六进制:

let orange = #colorLiteral(red: 1, green: 0.5763723254, blue: 0, alpha: 1)

但这仍然是一种简单的方法,可以在没有任何第三方工具或扩展的情况下粘贴十六进制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接