Ios 如何比较日志中的kCGColorSpaceModelRGB和UIExtendedSRGBColorSpace实例这两个UIColor对象?
现在我真的很困惑。 以下是如何实例化变量:Ios 如何比较日志中的kCGColorSpaceModelRGB和UIExtendedSRGBColorSpace实例这两个UIColor对象?,ios,swift,swift3,uicolor,Ios,Swift,Swift3,Uicolor,现在我真的很困惑。 以下是如何实例化变量: Utils.redColor = UIColor(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue)/255.0, alpha: alpha) 这里我列举了一个属性文本的属性,如果它等于Utils.redColor,则跳过该颜色: text.enumerateAttributes(in: NSRange(0..<text.lengt
Utils.redColor = UIColor(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue)/255.0, alpha: alpha)
这里我列举了一个属性文本的属性,如果它等于Utils.redColor,则跳过该颜色:
text.enumerateAttributes(in: NSRange(0..<text.length), options: []) { (attributes, range, _) -> Void in
for (attribute, object) in attributes {
if let textColor = object as? UIColor{
NSLog("textColor = \(textColor) red = \(Utils.redColor!)")
if (!textColor.isEqual(Utils.redColor!)){
//I need to repaint any textColor other than red
text.setAttributes(textAttributes , range: range)
}
}
这是两种完全相同的颜色,但属于两个不同类别的实例。这是完全混乱的,因为它们都是UIColor类的对象
这种比较从未触发,尽管它在Swift2中运行良好
我该如何解决它以及为什么会出现此问题???欢迎来到宽颜色和颜色管理的混乱世界 根据
isEqual
(或Swift=
,这两种颜色不相等,因为它们具有不同的颜色空间。(它们不是不同的类;UIColor.description
中的第一项是颜色空间的标识符,或者在颜色空间没有名称的情况下,是颜色空间的模型-也就是说,它是否基于RGB、CMYK、灰度等。)
如果没有颜色空间将其定义为颜色,则颜色的四个分量值没有可靠的含义,因此isEqual
使用分量值和颜色空间来测试相等性
在颜色空间上放在一边(向下跳以获取解决方案)
使用UIColor
创建的颜色使用“扩展sRGB”颜色空间。此颜色空间设计用于支持宽颜色显示(如iPhone 7中的P3颜色显示、iPad Pro 9.7、2015年底的iMac、2016年底的MacBook Pro,以及其他可能出现的功能),但其组件价值与其他设备上使用的sRGB颜色空间兼容
例如,sRGB1.0、0.0、0.0
是“红色”“你可能最习惯于。。。但是,如果在P3颜色空间中创建RGB值为1.0、0.0、0.0
的颜色,则颜色会变得更红。如果你有一个应用程序,需要同时支持sRGB和P3显示,并直接使用颜色组件,这可能会让人困惑。因此,扩展的sRGB空间允许相同的组件值表示相同的内容,但也允许使用0.0
-1.0
范围之外的值指定sRGB范围之外的颜色。例如,Display P3可以获得的最红颜色在扩展的sRGB中表示为(大致)1.093、-0.227、-0.15
正如该初始值设定项的文档所述,对于与iOS 10或更高版本SDK链接的应用程序,init(红色:绿色:蓝色:alpha:)
在扩展的sRGB颜色空间中创建颜色,但对于较旧的应用程序(即使它们在iOS 10上运行),它在特定于设备的RGB空间中创建颜色(通常可以将其视为等同于sRGB)
处理不同的颜色空间
因此,您的颜色替换代码或任何在属性字符串中创建颜色的代码都需要注意颜色空间。有几种可能的方法可以解决此问题;选择最适合您的方法:
UIColor
没有提供许多用于处理颜色空间的实用程序,因此您可以(在iOS 10及更高版本上)或下拉到CGColor
:
let sRGB = CGColorSpace(name: CGColorSpace.sRGB)!
let cgDarkRed = CGColor(colorSpace: sRGB, components: [0.666667, 0.172549, 0.172549, 1])!
let darkRed = UIColor(cgColor: cgDarkRed)
// example creating attributed string...
let attrString = NSAttributedString(string: "red", attributes: [NSForegroundColorAttributeName : darkRed])
// example processing text...
let redAttributes = [NSForegroundColorAttributeName: darkRed]
text.enumerateAttributes(in: NSRange(0..<attrString.length)) { (attributes, range, stop) in
for (_, textColor) in attributes where (textColor as? UIColor) != darkRed {
text.setAttributes(redAttributes , range: range)
}
}
(然后,您可以在文本处理中使用此函数代替=
或isEqual
。)在我看来,textColor和redColor实际上都是UIColor,但在不同的颜色空间中。请参阅UIColor扩展哦,太好了,谢谢你的深入回答。我向各种熟练的iOS开发人员问了这样一个问题,但没有得到答案。在android开发之后,有很多事情让我非常困惑。再次感谢你还是答案,我找了很长时间的解决方案!
let sRGB = CGColorSpace(name: CGColorSpace.sRGB)!
let cgDarkRed = CGColor(colorSpace: sRGB, components: [0.666667, 0.172549, 0.172549, 1])!
let darkRed = UIColor(cgColor: cgDarkRed)
// example creating attributed string...
let attrString = NSAttributedString(string: "red", attributes: [NSForegroundColorAttributeName : darkRed])
// example processing text...
let redAttributes = [NSForegroundColorAttributeName: darkRed]
text.enumerateAttributes(in: NSRange(0..<attrString.length)) { (attributes, range, stop) in
for (_, textColor) in attributes where (textColor as? UIColor) != darkRed {
text.setAttributes(redAttributes , range: range)
}
}
extension UIColor {
func isEqualWithConversion(_ color: UIColor) -> Bool {
guard let space = self.cgColor.colorSpace
else { return false }
guard let converted = color.cgColor.converted(to: space, intent: .absoluteColorimetric, options: nil)
else { return false }
return self.cgColor == converted
}
}