How to display animated GIF in Objective C on top of the layered View?

ColdSteel picture ColdSteel · May 31, 2014 · Viewed 11.8k times · Source

I am trying to draw animated gif on my screen in mac OSX app . I used this code to insert the gif: I can see the Gif as 1 picture it doesn't animates only static picture :( what should I add to make it animated ?

#import <Cocoa/Cocoa.h>
#import <Quartz/Quartz.h>//for drawing circle
#import "sharedPrefferences.h"
@interface GenericFanSubView : NSView
{
    NSColor * _backgroundColor;
    NSImageView* imageView;
}

- (void)setBackgroundColor :(NSColor*)color;

- (void)insertGif1;
- (void)insertGif2;
- (void)insertGif3;
@end

#import "GenericFanSubView.h"
#define PI 3.14285714285714

@implementation GenericFanSubView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
    // Initialization code here.
            imageView = [[NSImageView alloc]initWithFrame:CGRectMake(0, 0,self.frame.size.width,self.frame.size.height)];

        [imageView setAnimates: YES];
    }
    return self;
}

- (void)drawRect:(NSRect)dirtyRect
{
    [super drawRect:dirtyRect];
    // Drawing code here.
    [self drawCircleInRect];
    _backgroundColor = [NSColor whiteColor];
    [self insertGif1];
}

-(void)drawCircleInRect
{
    //draw colored circle here
    CGContextRef context = [[NSGraphicsContext // 1
                         currentContext] graphicsPort];
    // ********** Your drawing code here ********** // 2
    CGContextSetFillColorWithColor(context,[self NSColorToCGColor:(_backgroundColor)]);
    float radius1 = self.frame.size.height/2;
    float startAngle = 0;
    float endAngle = endAngle = PI*2;
    CGPoint position =  CGPointMake(self.frame.size.height/2,self.frame.size.height/2);//center of the view
    CGContextBeginPath(context);
    CGContextAddArc(context, position.x, position.y, radius1, startAngle, endAngle, 1);
    CGContextDrawPath(context, kCGPathFill); // Or kCGPathFill
}
- (void)setBackgroundColor :(NSColor*)color
{
    _backgroundColor = color;

    [self setNeedsDisplay:YES];
}

- (CGColorRef)NSColorToCGColor:(NSColor *)color
{
    NSInteger numberOfComponents = [color numberOfComponents];
    CGFloat components[numberOfComponents];
    CGColorSpaceRef colorSpace = [[color colorSpace] CGColorSpace];
    [color getComponents:(CGFloat *)&components];
    CGColorRef cgColor = CGColorCreate(colorSpace, components);
    return cgColor;
}

//curentlly calling only this 1
- (void)insertGif1
{
    [imageView removeFromSuperview];

     [imageView setImageScaling:NSImageScaleNone];

     [imageView setAnimates: YES];

     imageView.image = [NSImage imageNamed:@"FanBlades11.gif"];

     [self addSubview:imageView];
 }

@end

Edit: I discovered the source of the problem: I was adding my class (that represents gif inside the circle) on top of RMBlurredView and the animations doesn't work when I adding it as subview ,However it works on all the other views I added.

Any ideas what could be the reason inside the RMBlurredView to stop my NSImageView from animating ?

Edit: I think [self setWantsLayer:YES]; is the reason I am not getting animations how can I still get the animation with this feature enabled?

Edit:

Here is a simple sample with my problem

http://snk.to/f-cdk3wmfn

my gif:This is my gif it is invisible on white background color

Answer

Daij-Djan picture Daij-Djan · May 31, 2014

"You must disable the autoscaling feature of the NSImageView for the animation playback to function. After you've done that, no extra programming required. It works like a charm!"

--http://www.cocoabuilder.com/archive/cocoa/108530-nsimageview-and-animated-gifs.html

imageView.imageScaling = NSImageScaleNone;
imageView.animates = YES;

needed for layer backed views:

if the image view is in a layer backed view or is layer backed itself:

imageView.canDrawSubviewsIntoLayer = YES;

working example using the question's own gif:

NSImageView *view = [[NSImageView alloc] initWithFrame:CGRectMake(10, 10, 50, 50)];
view.imageScaling = NSImageScaleNone;
view.animates = YES;
view.image = [NSImage imageNamed:@"FanBlades2_42x42.gif"];
view.canDrawSubviewsIntoLayer = YES;

NSView *layerview = [[NSView alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];
layerview.wantsLayer = YES;
[layerview addSubview:view];

[self.window.contentView addSubview:layerview];