5

Basically all I want to do is to compare a layer.fillColor which is a CGColor with UIColor.black.cgColor.

The function CGColorEqualToColor is now deprecated in Swift 4.

I have tried:

if(layer.fillColor === UIColor.black.cgColor){
          return      
}

And it still doesn't work. I guess they must have the same kCGColorSpaceModel.

This is the output of each color in logs

<CGColor 0x1c02a15c0> [<CGColorSpace 0x1c02a0a20> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1; extended range)] ( 0 0 0 1 )
<CGColor 0x1c008e290> [<CGColorSpace 0x1c02a0f60> (kCGColorSpaceICCBased; kCGColorSpaceModelMonochrome; Generic Gray Gamma 2.2 Profile; extended range)] ( 0 1 )

What's the solution?

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Tarek hemdan
  • 874
  • 2
  • 10
  • 24
  • Implement a [color difference measure](https://en.wikipedia.org/wiki/Color_difference). If you limit yourself to RGB or sRGB, it's pretty simple – Code Different Jan 03 '18 at 16:59
  • `CGColorEqualToColor` has the same problem as `==` in that it checks the colour space, so it wouldn't help if it wasn't deprecated. – JeremyP Jan 03 '18 at 17:13

4 Answers4

2

CGColor has a method converted(to:intent:options:)

So maybe you could have a method as follows:

extension CGColor
{
    func compareConvertingColorSpace(other: CGColor) -> Bool 
    {
        let approximateColor = other.converted(to: self.colorSpace! intent: .defaultIntent, options nil) // fatal errror with no color space
        return self == approximateColor 
    }
}
JeremyP
  • 84,577
  • 15
  • 123
  • 161
2
extension CGColor {
    func same(as another: CGColor) -> Bool {
        let components = components ?? []
        let anotherComponents = another.components ?? []
        return zip(components, anotherComponents).allSatisfy { abs($0 - $1) < 1e-4 }
    }
}

You can use this as:

let sameBorderColor:Bool = borderColor.isSame(as: testBorderColor)

1

Here's an extension for CGColor that checks if the given color is black or not. This works with colors in the RGB and greyscale color spaces.

extension CGColor {
    func isBlack() -> Bool {
        let count = numberOfComponents
        if count > 1 {
            if let components = components {
                for c in 0..<components.count-1 { // skip the alpha component
                    // All components are 0 for black
                    if components[c] != 0.0 {
                        return false
                    }
                }

                return true
            }
        }

        return false
    }
}

print(UIColor.black.cgColor.isBlack())
print(UIColor(red: 0, green: 0, blue: 0, alpha: 1).cgColor.isBlack())

You can use this as:

if layer.fillColor.isBlack() {
    return
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
0

I would suggest to convert the 2 colours to Strings and then compare them normal. To convert them to strings, there is an answer for that https://stackoverflow.com/a/14051861/3342901.

Ashraf Tawfeeq
  • 3,036
  • 1
  • 20
  • 34