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

12,019

"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];
Share:
12,019
Coldsteel48
Author by

Coldsteel48

Employee of Waves Audio LLC Currently developing various OS X Audio filters. Independent developing. Currently developing a sprite kit Game called Jumping Julie I assume to finish development in the next week. From there it is all in hands of app store review team. It's finally online: https://itunes.apple.com/jp/app/jumping-julie/id987021239?mt=8&ign-mpt=uo%3D2 My free iOS Games (for kids) Earth Saving Max https://itunes.apple.com/us/app/earth-saving-max/id968434051?ls=1&mt=8 Bugy Boogie https://itunes.apple.com/us/app/bugy-boogie/id961421658?ls=1&mt=8

Updated on June 09, 2022

Comments

  • Coldsteel48
    Coldsteel48 almost 2 years

    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

  • Coldsteel48
    Coldsteel48 almost 10 years
    Tried this [imageView setImageScaling:NSImageScaleNone]; didn't help :(
  • Coldsteel48
    Coldsteel48 almost 10 years
    I set yes , still static :(
  • Coldsteel48
    Coldsteel48 almost 10 years
    When i click on it inside xCode it animates fine.
  • Coldsteel48
    Coldsteel48 almost 10 years
    in preview app it doesn't animated but i see all the frames on the left side.
  • Coldsteel48
    Coldsteel48 almost 10 years
    need at least 10 reputation to attach images
  • Fonix
    Fonix almost 10 years
    you now have over 10 rep :)
  • Coldsteel48
    Coldsteel48 almost 10 years
    the gif is white colour and transparent. so I linked it below
  • Coldsteel48
    Coldsteel48 almost 10 years
    But it doesn't for me :( Can you paste how u did it ? the code I mean .
  • Coldsteel48
    Coldsteel48 almost 10 years
    Well I posted all the relevant code... it is subclassed ... and the super class calls the function I posted.
  • Coldsteel48
    Coldsteel48 almost 10 years
    I don't use xibs sorry , thanks for code.. i can see only difference is : you are setting imageView.image. and I calling setImage method I will try like you did maybe it differs somewhere :)
  • Coldsteel48
    Coldsteel48 almost 10 years
    I tried all the same :( ... why everything is so hard in cocoa ?
  • Coldsteel48
    Coldsteel48 almost 10 years
    I will paste all the class here
  • Coldsteel48
    Coldsteel48 almost 10 years
    Yes I have 3 gifs so I am switching between them , but till now i called it only once to check it is working at all.. and it is not :(
  • Coldsteel48
    Coldsteel48 almost 10 years
    When I add it in my application directly to the appDelegate it also works fine... what could brake the behaviour when I adding it in to the NSView that is on the Window ?
  • Coldsteel48
    Coldsteel48 almost 10 years
    Updated my question Atleast i found a source of my problem .
  • wigging
    wigging almost 10 years
    Apparently canDrawSubviewsIntoLayer is only supported in OSX 10.9 and up. So how do you support animated gifs in layer backed views in 10.7 and 10.8? I have posted my question on SO stackoverflow.com/questions/24835853/…. Please help figure this out.
  • bauerMusic
    bauerMusic over 7 years
    If you checked the Storyboard 'Animates' box of the ImageView and it fail to animate. Well, seems the animates param of the NSImageView is either not the same as the Storyboard or simply the it does not parse that param. In short, do it in code, not in the storyboard. Worked for different scaling as well.