如何在Swift 3.0中将String转换为UIColor?

时间:2016-12-15 11:23:12

标签: ios swift3 selector uicolor

我正在尝试转换现有程序,该程序使用从Objective-C到Swift的预定义颜色列表。 原始代码使用Selector根据名称UIColor

的名称提取NSString
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]

-(UIColor *)getColor:(NSString*)colorName
{
    SEL selColor = NSSelectorFromString(colorName);
    NSString *errorMessage = [NSString stringWithFormat:@"Invalid color name: %@ !!!", colorName];
    NSAssert([UIColor respondsToSelector:selColor] == YES, errorMessage);
    UIColor *mycolor = [UIColor performSelector:selColor];
    return mycolor;
}

+ (instancetype)turquoiseColor {
    return UIColorFromRGB(0x40E0D0);
}

+ (instancetype)mediumTurquoiseColor {
    return UIColorFromRGB(0x48D1CC);
}

但是,我一直无法弄清楚如何使用Swift 3.0实现相同的功能,或者使用Selector是否是最好的技术。

func UIColorFromRGB(_ rgbValue: UInt) -> UIColor {
    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)
    )
}

extension UIColor {
    public class var turquoise: UIColor { return UIColorFromRGB(0x40E0D0) }
}

extension UIColor {
    public class var mediumTurquoise: UIColor { return UIColorFromRGB(0x48D1CC) }
}

let myColor: UIColor = .turquoise

let name: String = "turquoise"
let colorName = "UIColor.\(name)"
let selector: Selector = NSSelectorFromString(colorName)

let colorSelected: UIColor = UIColor.perform(selector!)
  

错误:!没有'执行'候选人产生预期的上下文结果类型'UIColor'

4 个答案:

答案 0 :(得分:3)

您可以创建一个默认值为String的Color枚举:

 enum Color: String {
   case red
   case blue
   case green

    var create: UIColor {
       switch self {
          case .red:
            return UIColor.red
        case .blue:
            return UIColor.blue
        case .green:
            return UIColor.green
       }
    }
  }

由于它的默认值为String,因此您可以使用字符串初始化枚举:

  guard let color = Color(rawValue: "red") else { "handle invalid color error"; return } 

 let colorSelected = color.create //// colorSelected is now UIColor.red

答案 1 :(得分:3)

您可以在Swift中编写类似于Objective-C代码的内容,如下所示:

extension UIColor {
    @objc(turquoiseColor)
    public class var turquoise: UIColor { return UIColorFromRGB(0x40E0D0) }
}

extension UIColor {
    @objc(mediumTurquoiseColor)
    public class var mediumTurquoise: UIColor { return UIColorFromRGB(0x48D1CC) }
}

let myColor: UIColor = .turquoise

func getColor(_ name: String) -> UIColor? {
    let selector = Selector("\(name)Color")
    if UIColor.self.responds(to: selector) {
        let color = UIColor.self.perform(selector).takeUnretainedValue()
        return (color as! UIColor)
    } else {
        return nil
    }
}

var name: String = "turquoise"
if let color = getColor(name) {
    print(color) //->UIExtendedSRGBColorSpace 0.25098 0.878431 0.815686 1
} else {
    print("color with name:\(name) is unavailable")
}

但使用Selector似乎并不是Swifty。

您可以简单地准备包含UIColor s:

的词典
let myColors: [String: UIColor] = [
    "red": .red,
    "white": .white,
    //...
    "turquoise": UIColorFromRGB(0x40E0D0),
    "mediumTurquoise": UIColorFromRGB(0x48D1CC),
]
name = "mediumTurquoise"
if let color = myColors[name] {
    print(color)
} else {
    print("color with name:\(name) is unavailable")
}

或JustinM的回答是一个非常好的建议。

答案 2 :(得分:3)

使用此onComponentOk扩展名,它有两种方法将RGBA字符串和十六进制字符串转换为UIColor

UIColor

答案 3 :(得分:0)

从OOPer的答案简化。我的情况是我没有颜色映射的集合。我必须直接从字符串中获取颜色。如果不存在,请使用其他方法。这是我的扩展名:

import UIKit

extension UIColor { 

    static func colorWith(name:String) -> UIColor? {
        let selector = Selector("\(name)Color")
        if UIColor.self.responds(to: selector) {
            let color = UIColor.self.perform(selector).takeUnretainedValue()
            return (color as? UIColor)
        } else {
            return nil
        }
    }
}

用法:

self.view.backgroundColor = UIColor.color(name: "red") ?? .blue