Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the new tintColor property of UIImageview in iOS 7 be used for animating images?

tintColor is a life saver, it takes app theming to a whole new (easy) level.

//the life saving bit is the new UIImageRenderingModeAlwaysTemplate mode of UIImage
UIImage *templateImage = [[UIImage imageNamed:@"myTemplateImage"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
imageView.image = templateImage;

//set the desired tintColor
imageView.tintColor = color;

The above code will "paint" the image's non-transparent parts according to the UIImageview's tint color which is oh so cool.No need for core graphics for something simple like that.

The problem I face is with animations.

Continuing from the above code:

//The array with the names of the images we want to animate
NSArray *imageNames = @[@"1",@"2"@"3"@"4"@"5"];

//The array with the actual images
NSMutableArray *images = [NSMutableArray new];
for (int i = 0; i < imageNames.count; i++)
{
    [images addObject:[[UIImage imageNamed:[imageNames objectAtIndex:i]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]];
}

//We set the animation images of the UIImageView to the images in the array
imageView.animationImages = images;

//and start animating the animation
[imageView startAnimating];

The animation is performed correctly but the images use their original color (i.e. the color used in the gfx editing application) instead of the UIImageView's tintColor.

I am about to try to perform the animation myself (by doing something a little bit over the top like looping through the images and setting the UIImageView's image property with a NSTimer delay so that the human eye can catch it).

Before doing that I'd like to ask if the tintColor property of UIImageView is supposed to support what I'm trying to do with it i.e use it for animations.

Thanks.

like image 544
joakim Avatar asked Oct 22 '13 15:10

joakim


1 Answers

Rather than animate the images myself, I decided to render the individual frames using a tint color and then let UIImage do the animation. I created a category on UIImage with the following methods:

+ (instancetype)animatedImageNamed:(NSString *)name tintColor:(UIColor *)tintColor duration:(NSTimeInterval)duration
{
    NSMutableArray *images = [[NSMutableArray alloc] init];

    short index = 0;
    while ( index <= 1024 )
    {
        NSString *imageName = [NSString stringWithFormat:@"%@%d", name, index++];
        UIImage *image = [UIImage imageNamed:imageName];
        if ( image == nil ) break;

        [images addObject:[image imageTintedWithColor:tintColor]];
    }

    return [self animatedImageWithImages:images duration:duration];
}

- (instancetype)imageTintedWithColor:(UIColor *)tintColor
{
    CGRect imageBounds = CGRectMake( 0, 0, self.size.width, self.size.height );

    UIGraphicsBeginImageContextWithOptions( self.size, NO, self.scale );
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM( context, 0, self.size.height );
    CGContextScaleCTM( context, 1.0, -1.0 );
    CGContextClipToMask( context, imageBounds, self.CGImage );

    [tintColor setFill];
    CGContextFillRect( context, imageBounds );

    UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return tintedImage;
}

It works just like + [UIImage animatedImageNamed:duration:] (including looking for files named "image0", "image1", etc) except that it also takes a tint color.

Thanks to this answer for providing the image tinting code: https://stackoverflow.com/a/19152722/321527

like image 165
Brian Avatar answered Oct 22 '22 09:10

Brian