基于进度值的UIColor转换

snk*_*snk 21 animation objective-c uicolor ios

我有一个ProgressBar,我想要为其指定一个customColor颜色,并根据进度淡入另一种颜色.使用下面的方法,我得到一个深色的彩虹效果颜色,包括红色,深棕色和深绿色.起始颜色为浅蓝色,目标颜色为浅绿色.

-(UIColor *) makeCustomColorFromProgressValue:(float) progress{


UIColor *color;

// startColor Color - lightBlue
float red = 0.53;
float green = 0.82;
float blue = 1;

//Destination Color - lightGreen
float finalRed = 0.53;
float finalGreen = 1;
float finalBlue = 0.82;

float newRed = 80;//finalRed *255;
float newGreen = (finalGreen *progress) *255;
float newBlue = (finalBlue *progress) *255;
color = Rgb2UIColor(newRed, newGreen, newBlue);



return color;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 24

您可以在颜色之间进行"线性插值":

CGFloat newRed   = (1.0 - progress) * red   + progress * finalRed;
CGFloat newGreen = (1.0 - progress) * green + progress * finalGreen;
CGFloat newBlue  = (1.0 - progress) * blue  + progress * finalBlue;
UIColor *color = [UIColor colorWithRed:newRed green:newGreen blue:newBlue alpha:1.0];
Run Code Online (Sandbox Code Playgroud)

这给出了初始颜色progress == 0和最终颜色 progress == 1.


Ati*_*ika 22

Swift版本从Jonathan Ellis的代码转换而来

extension UIColor {
    func interpolateRGBColorTo(_ end: UIColor, fraction: CGFloat) -> UIColor? {
        let f = min(max(0, fraction), 1)

        guard let c1 = self.cgColor.components, let c2 = end.cgColor.components else { return nil }

        let r: CGFloat = CGFloat(c1[0] + (c2[0] - c1[0]) * f)
        let g: CGFloat = CGFloat(c1[1] + (c2[1] - c1[1]) * f)
        let b: CGFloat = CGFloat(c1[2] + (c2[2] - c1[2]) * f)
        let a: CGFloat = CGFloat(c1[3] + (c2[3] - c1[3]) * f)

        return UIColor(red: r, green: g, blue: b, alpha: a)
    }
}

let color1 = UIColor(red: 0.035, green: 0.216, blue: 0.933, alpha: 1.00)
let color2 = UIColor(red: 0.933, green: 0.794, blue: 0.000, alpha: 1.00)

color1.interpolateRGBColorTo(color2, fraction:0.1)
Run Code Online (Sandbox Code Playgroud)

UIColor插值

  • 小心这一点,因为并非每个UIColor都有4个组件.如果颜色是这样创建的:`UIColor(白色:101.0/255.0,alpha:1.0)`那么颜色将只有2个组件,这将崩溃. (3认同)
  • 这会使颜色变得像这样的'UIColor(白色:0.0,alpha:0.4)` (2认同)

Jon*_*lis 14

这是一个类别UIColor,可用于UIColor在RGB或HSV中的两个s 之间进行线性插值:

@implementation UIColor (Interpolate)

+ (UIColor *)interpolateRGBColorFrom:(UIColor *)start to:(UIColor *)end withFraction:(float)f {

    f = MAX(0, f);
    f = MIN(1, f);

    const CGFloat *c1 = CGColorGetComponents(start.CGColor);
    const CGFloat *c2 = CGColorGetComponents(end.CGColor);

    CGFloat r = c1[0] + (c2[0] - c1[0]) * f;
    CGFloat g = c1[1] + (c2[1] - c1[1]) * f;
    CGFloat b = c1[2] + (c2[2] - c1[2]) * f;
    CGFloat a = c1[3] + (c2[3] - c1[3]) * f;

    return [UIColor colorWithRed:r green:g blue:b alpha:a];
}

+ (UIColor *)interpolateHSVColorFrom:(UIColor *)start to:(UIColor *)end withFraction:(float)f {

    f = MAX(0, f);
    f = MIN(1, f);

    CGFloat h1,s1,v1,a1;
    [start getHue:&h1 saturation:&s1 brightness:&v1 alpha:&a1];

    CGFloat h2,s2,v2,a2;
    [end getHue:&h2 saturation:&s2 brightness:&v2 alpha:&a2];

    CGFloat h = h1 + (h2 - h1) * f;
    CGFloat s = s1 + (s2 - s1) * f;
    CGFloat v = v1 + (v2 - v1) * f;
    CGFloat a = a1 + (a2 - a1) * f;

    return [UIColor colorWithHue:h saturation:s brightness:v alpha:a];
}

@end
Run Code Online (Sandbox Code Playgroud)


mt8*_*t81 14

上面提供的swift版本不适用于白色,这里是解决方案:

struct ColorComponents {
    var r:CGFloat, g:CGFloat, b:CGFloat, a:CGFloat
}

extension UIColor {

    func getComponents() -> ColorComponents {
        if (cgColor.numberOfComponents == 2) {
          let cc = cgColor.components!
          return ColorComponents(r:cc[0], g:cc[0], b:cc[0], a:cc[1])
        }
        else {
          let cc = cgColor.components!
          return ColorComponents(r:cc[0], g:cc[1], b:cc[2], a:cc[3])
        }
    }

    func interpolateRGBColorTo(end: UIColor, fraction: CGFloat) -> UIColor {
        var f = max(0, fraction)
        f = min(1, fraction)

        let c1 = self.getComponents()
        let c2 = end.getComponents()

        let r = c1.r + (c2.r - c1.r) * f
        let g = c1.g + (c2.g - c1.g) * f
        let b = c1.b + (c2.b - c1.b) * f
        let a = c1.a + (c2.a - c1.a) * f

        return UIColor.init(red: r, green: g, blue: b, alpha: a)
    }

}

let color1 = UIColor.whiteColor()
let color2 = UIColor(red: 0.933, green: 0.794, blue: 0.000, alpha: 1.00)

color1.interpolateRGBColorTo(color2, fraction:0.1)
color1.interpolateRGBColorTo(color2, fraction:0.2)
color1.interpolateRGBColorTo(color2, fraction:0.3)
Run Code Online (Sandbox Code Playgroud)

❤︎游乐场


elc*_*uco 6

swift的另一个端口,作为UIColor的扩展.这次都是插值功能.

extension UIColor {
    func interpolateRGBColorTo(end:UIColor, fraction:CGFloat) -> UIColor {
        var f = max(0, fraction)
        f = min(1, fraction)
        let c1 = CGColorGetComponents(self.CGColor)
        let c2 = CGColorGetComponents(end.CGColor)
        let r: CGFloat = CGFloat(c1[0] + (c2[0] - c1[0]) * f)
        let g: CGFloat = CGFloat(c1[1] + (c2[1] - c1[1]) * f)
        let b: CGFloat = CGFloat(c1[2] + (c2[2] - c1[2]) * f)
        let a: CGFloat = CGFloat(c1[3] + (c2[3] - c1[3]) * f)
        return UIColor.init(red:r, green:g, blue:b, alpha:a)
    }

    func interpolateHSVColorFrom(end: UIColor, fraction: CGFloat) -> UIColor {
        var f = max(0, fraction)
        f = min(1, fraction)
        var h1: CGFloat = 0, s1: CGFloat = 0, b1: CGFloat = 0, a1: CGFloat = 0
        self.getHue(&h1, saturation: &s1, brightness: &b1, alpha: &a1)
        var h2: CGFloat = 0, s2: CGFloat = 0, b2: CGFloat = 0, a2: CGFloat = 0
        end.getHue(&h2, saturation: &s2, brightness: &b2, alpha: &a2)
        let h = h1 + (h2 - h1) * f
        let s = s1 + (s2 - b1) * f
        let b = b1 + (b2 - b1) * f
        let a = a1 + (a2 - a1) * f
        return UIColor(hue: h, saturation: s, brightness: b, alpha: a)
    }
}
Run Code Online (Sandbox Code Playgroud)