Get Slightly Lighter and Darker Color from UIColor

前端 未结 19 2385
猫巷女王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:43

    Ideally, the functions should be encapsulated inside a UIColor extension called, UIColor+Brightness.swift, and have a configurable brightness - see example below:

    import UIKit
    
    extension UIColor {
    
      func lighterColorWithBrightnessFactor(brightnessFactor:CGFloat) -> 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 + brightnessFactor, 1.0),
            green:min(g + brightnessFactor, 1.0),
            blue:min(b + brightnessFactor, 1.0),
            alpha:a)
        }
        return UIColor()
      }
    
    }
    
    0 讨论(0)
  • 2020-12-07 07:44

    All other answers in this thread use either the RGB color system or simply change the hue or brightness value of the HSB system. As explained in detail in this great blog post the correct way of making a color lighter or darker is to change its luminance value. None of the other answers does that. If you want to do it right, then use my solution or write your own after reading the blog post.


    Unfortunately it's quite a hassle to change any of the attributes of a UIColor by default. Also Apple doesn't even support any LAB-based color space like HCL in the UIColor class (the L in LAB is the luminance value we are looking for).

    Using HandyUIKit (install it via Carthage) adds support for HCL and makes your life a lot easier:

    import HandyUIKit    
    
    let color = UIColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 1.0)
    
    // create a new UIColor object with a specific luminance (slightly lighter)
    color.change(.luminance, to: 0.7)
    

    There is also an option to apply a relative change (recommended):

    // create a new UIColor object with slightly darker color
    color.change(.luminance, by: -0.2)
    

    Note that HandyUIKit also adds some other handy UI features into your project – checkout its README on GitHub for more details.

    I hope it helps!

    Disclaimer: I'm the author of HandyUIKit.

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

    If you convert the RGB color to the HSL color model then you can vary the L = lightness component from L = 0.0 (black) over L = 0.5 (natural color) to L = 1.0 (white) . UIColor cannot handle HSL directly, but there are formula for converting RGB <-> HSL.

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

    I just wanted to give the same result, in RGB, than

    • placing the color with alpha x% over a white background to lighten
    • placing the color with alpha x% over a black background to darken

    Which gives the same result, AFAIK, than picking the color in a gradient 'color to white' or 'color to black', at x% of the gradient size.

    For that purpose, the math is simple:

    extension UIColor {
        func mix(with color: UIColor, amount: CGFloat) -> UIColor {
            var red1: CGFloat = 0
            var green1: CGFloat = 0
            var blue1: CGFloat = 0
            var alpha1: CGFloat = 0
    
            var red2: CGFloat = 0
            var green2: CGFloat = 0
            var blue2: CGFloat = 0
            var alpha2: CGFloat = 0
    
            getRed(&red1, green: &green1, blue: &blue1, alpha: &alpha1)
            color.getRed(&red2, green: &green2, blue: &blue2, alpha: &alpha2)
    
            return UIColor(
                red: red1 * (1.0 - amount) + red2 * amount,
                green: green1 * (1.0 - amount) + green2 * amount,
                blue: blue1 * (1.0 - amount) + blue2 * amount,
                alpha: alpha1
            )
        }
    }
    

    Here are examples with some colors

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

    If you want user529758's solution to work with gray shades (like [UIColor lightGrayColor] or [UIColor darkGrayColor] you have to improve it like that:

    - (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];
        }
    
        CGFloat white, alpha;
        if ([self getWhite:&white alpha:&alpha]) {
            white = MIN(1.3*white, 1.0);
            return [UIColor colorWithWhite:white alpha:alpha];
        }
    
        return nil;
    }
    

    getHue:saturation:brightness:alpha fails (and returns false) when called on a gray shade therefore you'll need to use getWhite:alpha.

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

    UIColor extension and fixing lighterColorForColor

    extension UIColor {
      class 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()
      }
    
      class 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){
          let tmpColor = UIColor(red: min(r + 0.2, 1.0), green: min(g + 0.2, 1.0), blue: min(b + 0.2, 1.0), alpha: a)
          println(tmpColor)
          return tmpColor
        }
        return UIColor()
      }
    }
    
    0 讨论(0)
提交回复
热议问题