e.g. The inverse color from black should be white.
10 Answers
---- 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;
}

- 2,500
- 6
- 32
- 48
-
this extremely old answer is very poor and should be deleted – Fattie Feb 02 '23 at 16:36
iOS5+
-(UIColor*) inverseColor
{
CGFloat r,g,b,a;
[self getRed:&r green:&g blue:&b alpha:&a];
return [UIColor colorWithRed:1.-r green:1.-g blue:1.-b alpha:a];
}

- 6,192
- 5
- 38
- 43
-
It's the same as "1.0"(double) or "1f"(float). It just informs the compiler that we'll be using a float instead of an integer. – carlossless Jan 23 '13 at 09:49
This should work:
// oldColor is the UIColor to invert
const CGFloat *componentColors = CGColorGetComponents(oldColor.CGColor);
UIColor *newColor = [[UIColor alloc] initWithRed:(1.0 - componentColors[0])
green:(1.0 - componentColors[1])
blue:(1.0 - componentColors[2])
alpha:componentColors[3]];
-
Thanks, your answer is very good. But if the oldColor is [UIColor colorWithWhite:1 alpha:1], the newColor will be transparent. – Míng May 05 '11 at 16:35
-
4This does only work with RGB colors. The answer by iwill below is better. – Christian Beer Aug 27 '13 at 07:45
Swift way is to extend UIColor:
extension UIColor {
func inverse () -> UIColor {
var r:CGFloat = 0.0; var g:CGFloat = 0.0; var b:CGFloat = 0.0; var a:CGFloat = 0.0;
if self.getRed(&r, green: &g, blue: &b, alpha: &a) {
return UIColor(red: 1.0-r, green: 1.0 - g, blue: 1.0 - b, alpha: a)
}
return .black // Return a default colour
}
}

- 5,396
- 4
- 31
- 54

- 188
- 1
- 6
-
1This doesn't deal with non-rgb color spaces so iwill's answer should be preferred. – steipete Nov 29 '15 at 11:18
-
Swift solution extending UIColor
to add a computed property inverted
:
extension UIColor {
var inverted: UIColor {
var a: CGFloat = 0.0, r: CGFloat = 0.0, g: CGFloat = 0.0, b: CGFloat = 0.0
return getRed(&r, green: &g, blue: &b, alpha: &a) ? UIColor(red: 1.0-r, green: 1.0-g, blue: 1.0-b, alpha: a) : .black
}
}
Use on any UIColor
instance (.red
, .blue
, .white
, etc.), for example:
view.backgroundColor = UIColor.blue.inverted //Results in yellow background
view.backgroundColor = UIColor.black.inverted //Results in white background

- 984
- 1
- 12
- 22
The solution from GRC has an issue: CGColorGetComponents returns in a scale of 0.0-1.0, and not from 2-255. So you should use
UIColor *newColor = [[UIColor alloc] initWithRed:(1.0 - componentColors[0])
green:(1.0 - componentColors[1])
blue:(1.0 - componentColors[2])
alpha:componentColors[3]];
instead. Else everything will be white (1.0 and lager)
kind of the same thing as amleszk used, there it's also 1.-color, instead of 255. Btw that 1. represents the float 1.0, you should rather type 1.0 in stead of 1., to avoid confusion

- 564
- 1
- 6
- 16
So to be helpful for all swifters came here looking for the answer - this is how it should look like in swift:
func inverseColor(color: UIColor) -> UIColor{
var a: CGFloat = 0.0; var r: CGFloat = 0.0; var g: CGFloat = 0.0; var b: CGFloat = 0.0;
color.getRed(&r, green: &g, blue: &b, alpha: &a);
return UIColor(red: -r, green: -g, blue: -b, alpha: a);
}

- 1,236
- 2
- 18
- 25
I used Dade's answer and tweaked it a bit because I was looking for a nice way of calculating a Text foreground color given a background color.
So if you wanted to get a nice Text color for a given background color, I would suggest you do this. It gives you the brightest color of your given background color:
extension UIColor {
func maxBright() -> UIColor {
var r:CGFloat = 0.0; var g:CGFloat = 0.0; var b:CGFloat = 0.0; var a:CGFloat = 0.0;
if self.getRed(&r, green: &g, blue: &b, alpha: &a) {
let d:CGFloat = 1.0 - max(r,g,b)
return UIColor(red: r + d, green: g + d , blue: b + d, alpha: 1.0)
}
return self
}
}
It works like sliding your RGB sliders up until the brightest component hits max.
Example:
titleLable.backgroundColor = UIColor.blackColor()
titleLabel.textColor = titleLabel.backgroundColor?.maxBright()
will give you a white on black Label. Try other colors and you'll see interesting results :)
This might not be what you were looking for but it does give interesting results for Text fore/back colors.
Just sharing

- 433
- 5
- 4
You did not get inverse colors for Gray.. So effects when you use gray back ground and its inverse color as text color
THIS Works even for gray color, i just added some additional code to @iWills code.
//====== TO GET THE OPPOSIT COLORS =====
-(UIColor *)reverseColorOf :(UIColor *)oldColor
{
CGColorRef oldCGColor = oldColor.CGColor;
int numberOfComponents = CGColorGetNumberOfComponents(oldCGColor);
// can not invert - the only component is the alpha
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);
//=====For the GRAY colors 'Middle level colors'
CGFloat white = 0;
[oldColor getWhite:&white alpha:nil];
if(white>0.3 && white < 0.67)
{
if(white >= 0.5)
newColor = [UIColor darkGrayColor];
else if (white < 0.5)
newColor = [UIColor blackColor];
}
return newColor;
}

- 2,902
- 2
- 18
- 21

- 641
- 2
- 10
- 21
-
The inverse of gray is gray. I know that's not super helpful for most practical purposes, but that's the mathematical reality. So "this works for gray" is relative; it'll only "work" if you're trying to get a color with high contrast from the source color. I do however really like how this answer deals with disparate or unknown colorspaces. – Falkreon Jul 26 '18 at 11:45
-