objective-ciosuicolorinverse

How to get inverse color from UIColor?


e.g. The inverse color from black should be white.


Solution

  • ---- EDIT ----

    Based on @amleszk's answer, I updated the UIColor extension/category with this method:

    Swift

    func inverseColor() -> UIColor {
        var alpha: CGFloat = 1.0
        
        var red: CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0
        if self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) {
            return UIColor(red: 1.0 - red, green: 1.0 - green, blue: 1.0 - blue, alpha: alpha)
        }
        
        var hue: CGFloat = 0.0, saturation: CGFloat = 0.0, brightness: CGFloat = 0.0
        if self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) {
            return UIColor(hue: 1.0 - hue, saturation: 1.0 - saturation, brightness: 1.0 - brightness, alpha: alpha)
        }
        
        var white: CGFloat = 0.0
        if self.getWhite(&white, alpha: &alpha) {
            return UIColor(white: 1.0 - white, alpha: alpha)
        }
        
        return self
    }
    

    Objective-C

    - (UIColor *)inverseColor {
        CGFloat alpha;
        
        CGFloat red, green, blue;
        if ([self getRed:&red green:&green blue:&blue alpha:&alpha]) {
            return [UIColor colorWithRed:1.0 - red green:1.0 - green blue:1.0 - blue alpha:alpha];
        }
        
        CGFloat hue, saturation, brightness;
        if ([self getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]) {
            return [UIColor colorWithHue:1.0 - hue saturation:1.0 - saturation brightness:1.0 - brightness alpha:alpha];
        }
        
        CGFloat white;
        if ([self getWhite:&white alpha:&alpha]) {
            return [UIColor colorWithWhite:1.0 - white alpha:alpha];
        }
        
        return nil;
    }
    

    ---- DEPRECATED ----

    Based on @grc's answer, I create a UIColor category with this method:

    - (UIColor *)inverseColor {
        
        CGColorRef oldCGColor = self.CGColor;
        
        int numberOfComponents = CGColorGetNumberOfComponents(oldCGColor);
        
        // can not invert - the only component is the alpha
        // e.g. self == [UIColor groupTableViewBackgroundColor]
        if (numberOfComponents == 1) {
            return [UIColor colorWithCGColor:oldCGColor];
        }
        
        const CGFloat *oldComponentColors = CGColorGetComponents(oldCGColor);
        CGFloat newComponentColors[numberOfComponents];
        
        int i = numberOfComponents - 1;
        newComponentColors[i] = oldComponentColors[i]; // alpha
        while (--i >= 0) {
            newComponentColors[i] = 1 - oldComponentColors[i];
        }
        
        CGColorRef newCGColor = CGColorCreate(CGColorGetColorSpace(oldCGColor), newComponentColors);
        UIColor *newColor = [UIColor colorWithCGColor:newCGColor];
        CGColorRelease(newCGColor);
        
        return newColor;
    }