e.g. The inverse color from black should be white.
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];
}
---- 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 white: CGFloat = 0.0
if self.getWhite(&white, alpha: &alpha) {
return UIColor(white: 1.0 - white, 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 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)
}
return self
}
// Objective-C
- (UIColor *)inverseColor {
CGFloat alpha;
CGFloat white;
if ([self getWhite:&white alpha:&alpha]) {
return [UIColor colorWithWhite:1.0 - white 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 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];
}
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;
}
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]];
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
}
}
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
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);
}
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;
}
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
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
来源:https://stackoverflow.com/questions/5893261/how-to-get-inverse-color-from-uicolor