Manually color fading from one UIColor to another

2019-04-22 21:53发布

问题:

I'm trying to fade one UIColor to another in a drawRect. I've created this function to calculate a color at a certain percentage:

- (UIColor *)colorFromColor:(UIColor *)fromColor toColor:(UIColor *)toColor percent:(float)percent
{
    float dec = percent / 100.f;
    CGFloat fRed, fBlue, fGreen, fAlpha;
    CGFloat tRed, tBlue, tGreen, tAlpha;
    CGFloat red, green, blue, alpha;

    if(CGColorGetNumberOfComponents(fromColor.CGColor) == 2) {
        [fromColor getWhite:&fRed alpha:&fAlpha];
        fGreen = fRed;
        fBlue = fRed;
    }
    else {
        [fromColor getRed:&fRed green:&fGreen blue:&fBlue alpha:&fAlpha];
    }
    if(CGColorGetNumberOfComponents(toColor.CGColor) == 2) {
        [toColor getWhite:&tRed alpha:&tAlpha];
        tGreen = tRed;
        tBlue = tRed;
    }
    else {
        [toColor getRed:&tRed green:&tGreen blue:&tBlue alpha:&tAlpha];
    }

    red = (dec * (tRed - fRed)) + fRed;
    blue = (dec * (tGreen - fGreen)) + fGreen;
    green = (dec * (tBlue - fBlue)) + fBlue;
    alpha = (dec * (tAlpha - fAlpha)) + fAlpha;

    return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}

What this does is takes each R/G/B/A value and increments it depending on the percentage.

It kind of works, but doesn't fade [UIColor purpleColor] to [UIColor redColor] correctly. At 0.1 percent it shows up as a green color rather than purple, so it appears to fade from green to red instead of purple to red.

Anyone know what I'm doing wrong? Is this the wrong approach to calculating this? Is there a more accurate way to do this?

回答1:

You've got your green and blue swapped on the last few lines.



回答2:

Updated version for swift

import UIKit

extension UIColor {
    // MARK: - UIColor+Percentage


    class func colorForProgress(progress:CGFloat) -> UIColor {

        var normalizedProgress = progress < 0 ?  0 : progress
        normalizedProgress = normalizedProgress > 1 ?  1 : normalizedProgress

        let R:CGFloat = 155.0 * normalizedProgress
        let G:CGFloat = 155.0 * (1 - normalizedProgress) 
        let B:CGFloat = 0.0

        return UIColor(red: R / 255.0, green: G / 255.0, blue: B / 255.0, alpha: 1)
    }

    class func transitionColor(fromColor:UIColor, toColor:UIColor, progress:CGFloat) -> UIColor {    

        var percentage = progress < 0 ?  0 : progress
        percentage = percentage > 1 ?  1 : percentage

        var fRed:CGFloat = 0
        var fBlue:CGFloat = 0
        var fGreen:CGFloat = 0
        var fAlpha:CGFloat = 0

        var tRed:CGFloat = 0
        var tBlue:CGFloat = 0
        var tGreen:CGFloat = 0
        var tAlpha:CGFloat = 0

        fromColor.getRed(&fRed, green: &fGreen, blue: &fBlue, alpha: &fAlpha)
        toColor.getRed(&tRed, green: &tGreen, blue: &tBlue, alpha: &tAlpha)

        let red:CGFloat = (percentage * (tRed - fRed)) + fRed;
        let green:CGFloat = (percentage * (tGreen - fGreen)) + fGreen;
        let blue:CGFloat = (percentage * (tBlue - fBlue)) + fBlue;
        let alpha:CGFloat = (percentage * (tAlpha - fAlpha)) + fAlpha;

        return UIColor(red: red, green: green, blue: blue, alpha: alpha)
    }
}