Get Slightly Lighter and Darker Color from UIColor

前端 未结 19 2387
猫巷女王i
猫巷女王i 2020-12-07 07:08

I was looking to be able to turn any UIColor into a gradient. The way I am intending to do this is by using Core Graphics to draw a gradient. What I am trying to do is to ge

相关标签:
19条回答
  • 2020-12-07 07:39
    - (UIColor *)lighterColorForColor:(UIColor *)c
    {
        CGFloat r, g, b, a;
        if ([c getRed:&r green:&g blue:&b alpha:&a])
            return [UIColor colorWithRed:MIN(r + 0.2, 1.0)
                                   green:MIN(g + 0.2, 1.0)
                                    blue:MIN(b + 0.2, 1.0)
                                   alpha:a];
        return nil;
    }
    
    - (UIColor *)darkerColorForColor:(UIColor *)c
    {
        CGFloat r, g, b, a;
        if ([c getRed:&r green:&g blue:&b alpha:&a])
            return [UIColor colorWithRed:MAX(r - 0.2, 0.0)
                                   green:MAX(g - 0.2, 0.0)
                                    blue:MAX(b - 0.2, 0.0)
                                   alpha:a];
        return nil;
    }
    

    Use it like this:

    UIColor *baseColor = // however you obtain your color
    UIColor *lighterColor = [self lighterColorForColor:baseColor];
    UIColor *darkerColor = [self darkerColorForColor:baseColor];
    

    EDIT: as @Anchu Chimala pointed out, for maximum flexibility, these methods should be implemented as an UIColor category. Also, from @Riley's idea, it may be a better idea to make the color proprtionally darker or lighter instead of adding or subtracting constant values. As @jrturton pointed out, it's not necessary to manipulate the RGB components; it's better to modify the brightness property itself. All in all:

    @implementation UIColor (LightAndDark)
    
    - (UIColor *)lighterColor
    {
        CGFloat h, s, b, a;
        if ([self getHue:&h saturation:&s brightness:&b alpha:&a])
            return [UIColor colorWithHue:h
                              saturation:s
                              brightness:MIN(b * 1.3, 1.0)
                                   alpha:a];
        return nil;
    }
    
    - (UIColor *)darkerColor
    {
        CGFloat h, s, b, a;
        if ([self getHue:&h saturation:&s brightness:&b alpha:&a])
            return [UIColor colorWithHue:h
                              saturation:s
                              brightness:b * 0.75
                                   alpha:a];
        return nil;
    }
    @end
    
    0 讨论(0)
  • 2020-12-07 07:39

    I'm not sure if you're looking for some sort of Objective-C answer, but based on how colors specified by RGBA work, I think you can simply scale the RGB values according to an arbitrary factor to get a "lighter" or "darker" shade. For example, you might have a blue:

    [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:1.0];
    

    Want a darker blue? Multiply the RGB values by 0.9:

    [UIColor colorWithRed:0.0 green:0.0 blue:0.9 alpha:1.0];
    

    Voila. Or maybe you have an orange:

    [UIColor colorWithRed:1.0 green:0.4 blue:0.0 alpha:1.0];
    

    Choose another scale factor, say, 0.8:

    [UIColor colorWithRed:0.8 green:0.32 blue:0.0 alpha:1.0];
    

    Is that the sort of effect you're looking for?

    0 讨论(0)
  • 2020-12-07 07:41

    None of the solutions posted quite worked for all colours and shades, but then I stumbled across this library which provides a set of very well implemented extensions to UIColor.

    Specifically it has a lighten function as part of its HSL implementation: (UIColor *)lighten:(CGFloat)amount - which works perfectly.

    0 讨论(0)
  • 2020-12-07 07:41

    I render coloured cells based on a status value:

    status-images

    For this I wrote a swift extension based on some old objc code after I got an error using CryingHippo's suggestion:

    extension UIColor{
    
        func darker(darker: CGFloat) -> UIColor{
    
            var red: CGFloat = 0.0
            var green: CGFloat = 0.0
            var blue: CGFloat = 0.0
    
            if self.colorSpace == UIColorSpace.genericGrayColorSpace(){
    
                red =  whiteComponent - darker
                green = whiteComponent - darker
                blue  = whiteComponent - darker
            } else {
                red = redComponent - darker
                green = greenComponent - darker
                blue = blueComponent - darker
            }
    
            if red < 0{
                green += red/2
                blue += red/2
            }
    
            if green < 0{
                red += green/2
                blue += green/2
            }
    
            if blue < 0{
                green += blue/2
                red += blue/2
            }
    
            return UIColor(
                calibratedRed: red,
                green: green,
                blue: blue,
                alpha: alphaComponent
            )
        }
    
        func lighter(lighter: CGFloat) -> UIColor{
            return darker(-lighter)
        }
    }
    

    The same works for NSColor as well. Simply replace UIColor with NSColor.

    0 讨论(0)
  • 2020-12-07 07:42

    user529758's solution in Swift:

    Darker color:

    func darkerColorForColor(color: UIColor) -> UIColor {
    
           var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0
    
           if color.getRed(&r, green: &g, blue: &b, alpha: &a){
               return UIColor(red: max(r - 0.2, 0.0), green: max(g - 0.2, 0.0), blue: max(b - 0.2, 0.0), alpha: a)
           }
    
           return UIColor()
    }
    

    Lighter color:

    func lighterColorForColor(color: UIColor) -> UIColor {
    
           var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0
    
           if color.getRed(&r, green: &g, blue: &b, alpha: &a){
               return UIColor(red: min(r + 0.2, 1.0), green: min(g + 0.2, 1.0), blue: min(b + 0.2, 1.0), alpha: a)
           }
    
           return UIColor()
    }
    
    0 讨论(0)
  • 2020-12-07 07:43

    Sebyffffd solution as an extension:

    extension UIColor {    
        func darker() -> UIColor {
    
            var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0
    
            if self.getRed(&r, green: &g, blue: &b, alpha: &a){
                return UIColor(red: max(r - 0.2, 0.0), green: max(g - 0.2, 0.0), blue: max(b - 0.2, 0.0), alpha: a)
            }
    
            return UIColor()
        }
    
        func lighter() -> UIColor {
    
            var r:CGFloat = 0, g:CGFloat = 0, b:CGFloat = 0, a:CGFloat = 0
    
            if self.getRed(&r, green: &g, blue: &b, alpha: &a){
                return UIColor(red: min(r + 0.2, 1.0), green: min(g + 0.2, 1.0), blue: min(b + 0.2, 1.0), alpha: a)
            }
    
            return UIColor()
        }
    }
    

    Usage:

    let darkerYellow = UIColor.yellow.darker()
    let lighterYellow = UIColor.yellow.lighter()
    
    0 讨论(0)
提交回复
热议问题