iOS开发学习iOS动画程序员

iOS-播放gif动画文件(OC方法)

2016-06-23  本文已影响3461人  volientDuan

iOS-.gif动画文件的播放

前言

播放gif动画的方法有多种:

  1. 将gif图片分解成多张图片使用UIImageView播放
  2. webView直接播放.gif文件
  3. 使用第三方播放

本文主要介绍的是这三种方法播放gif动画,并提供一个使用第三种方法制作的播放gif的loading实例。接下就步入正题吧(__)!


为了方便大家使用封装了一个可以在任意VIEW播放gif动画的工具类,欢迎使用!

VDGifPlayerTool.h

#import <Foundation/Foundation.h>

@interface VDGifPlayerTool : NSObject

- (void)addGifWithName:(NSString *)gifName toView:(UIView *)view;

@end

VDGifPlayerTool.m

#import "VDGifPlayerTool.h"
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>

@interface VDGifPlayerTool()
@property (nonatomic, strong)UIView *gifContentView;

@property (nonatomic, assign)CGImageSourceRef gif;
@property (nonatomic, strong)NSDictionary *gifDic;
@property (nonatomic, assign)size_t index;
@property (nonatomic, assign)size_t count;
@property (nonatomic, strong)NSTimer *timer;

@end
@implementation VDGifPlayerTool

- (void)addGifWithName:(NSString *)gifName toView:(UIView *)view{
    self.gifContentView = view;
    [self createGif:gifName];
}

- (void)createGif:(NSString *)name{
    
    //    _gifContentView.layer.borderColor = UIColorFromRGB(No_Choose_Color).CGColor;
    //    _gifContentView.layer.borderWidth = 1.0;
    NSDictionary *gifLoopCount = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount];
    _gifDic = [NSDictionary dictionaryWithObject:gifLoopCount forKey:(NSString *)kCGImagePropertyGIFDictionary];
    
    NSData *gif = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]];
    _gif = CGImageSourceCreateWithData((CFDataRef)gif, (CFDictionaryRef)_gifDic);
    _count = CGImageSourceGetCount(_gif);
    _timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(startLoading) userInfo:nil repeats:YES];
    [_timer fire];
}
-(void)startLoading
{
    _index ++;
    _index = _index%_count;
    CGImageRef ref = CGImageSourceCreateImageAtIndex(_gif, _index, (CFDictionaryRef)_gifDic);
    self.gifContentView.layer.contents = (__bridge id)ref;
    CFRelease(ref);
}
- (void)dealloc{
    if (_gif) {
        CFRelease(_gif);
    }
}
@end

一、UIImageView实现gif动画

用imageView制作gif动画最经典就是汤姆猫,感兴趣的可以百度或者谷歌一下“iOS汤姆猫源代码”。在这里只是简单的介绍imageview的gif动画实现,你也可以用计时器(NSTimer).在做这些之前必须要将gif分解成一张张PNG图片。

UIImageView *gifImageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
    gifImageView.center = self.view.center;
    [self.view addSubview:gifImageView];
    
    NSMutableArray *images = [NSMutableArray array];
    for (int i=0; i < 10; i++) {
        [images addObject:[UIImage imageNamed:[NSString stringWithFormat:@"image%d",i]]];
    }
    gifImageView.animationImages = images;
    gifImageView.animationDuration = 5.0;
    gifImageView.animationRepeatCount = NSUIntegerMax;
    [gifImageView startAnimating];

二、UIWebView实现.gif动画文件的播放

webView可以加载很多文件是个很强大的控件,实现gif播放简单直接不过只能循环播放。

CGSize size = [UIImage imageNamed:@"name.gif"].size;
    UIWebView *webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, size.width, size.height)];
    webView.center = self.view.center;
    webView.userInteractionEnabled = NO;
    webView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:webView];
    NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"name" ofType:@"gif"]];
    [webView loadData:data MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];

三、第三方实现播放gif动画

首先需要导入两个库:ImageIO.frameworkMobileCoreServices.framework;具体实现是采用ImageIO库对.gif文件进行解析获取相关资源最后进行动画的播放,下面是自己写的播放gif动画的loading实例(比较简陋大家将就看看,知道怎么实现就行了_)。

GifLoadingView.h

#import <UIKit/UIKit.h>

@interface GifLoadingView : UIView
+(void)startLoading;
+(void)endLoading;
@end

GifLoadingView.m

#define  GIF_WIDTH 80*1.2
#import "GifLoadingView.h"
#import <ImageIO/ImageIO.h>
#import <MobileCoreServices/MobileCoreServices.h>
@interface GifLoadingView()
@property (nonatomic, strong)NSMutableArray<UIImage *> *images;
@property (nonatomic, strong)GifLoadingView *loading;
@property (nonatomic, strong)UIView *gifContentView;

@property (nonatomic, assign)CGImageSourceRef gif;
@property (nonatomic, strong)NSDictionary *gifDic;
@property (nonatomic, assign)size_t index;
@property (nonatomic, assign)size_t count;
@property (nonatomic, strong)NSTimer *timer;

@end
@implementation GifLoadingView
- (instancetype)init{
    self = [self initWithFrame:CGRectMake(0, 0, GIF_WIDTH, GIF_WIDTH)];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        self.layer.cornerRadius = GIF_WIDTH/2;
        self.layer.masksToBounds = YES;
        [self createGif];

    }
    return self;
}

- (void)createGif{
    
//    _gifContentView.layer.borderColor = UIColorFromRGB(No_Choose_Color).CGColor;
//    _gifContentView.layer.borderWidth = 1.0;
    NSDictionary *gifLoopCount = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount];
    _gifDic = [NSDictionary dictionaryWithObject:gifLoopCount forKey:(NSString *)kCGImagePropertyGIFDictionary];

    NSData *gif = [NSData dataWithContentsOfFile: [[NSBundle mainBundle] pathForResource:@"loading" ofType:@"gif"]];
    _gif = CGImageSourceCreateWithData((CFDataRef)gif, (CFDictionaryRef)_gifDic);
    _count = CGImageSourceGetCount(_gif);
    _timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(startLoading) userInfo:nil repeats:YES];
    [_timer fire];
}
-(void)startLoading
{
    _index ++;
    _index = _index%_count;
    CGImageRef ref = CGImageSourceCreateImageAtIndex(_gif, _index, (CFDictionaryRef)_gifDic);
    self.layer.contents = (__bridge id)ref;
    CFRelease(ref);
}
+ (void)startLoading{
    GifLoadingView *loading = [[GifLoadingView alloc]init];
    UIWindow *keyView = [UIApplication sharedApplication].keyWindow;
    loading.center = keyView.center;
    [keyView addSubview:loading];
    dispatch_main_after(5.0f, ^{
        [GifLoadingView endLoading];
    });
}
+ (void)endLoading{
    for (UIView *view in [UIApplication sharedApplication].keyWindow.subviews) {
        if ([view isKindOfClass:[GifLoadingView class]]) {
//            [UIView animateWithDuration:1.0 animations:^{
//                view.alpha = 0;
//            } completion:^(BOOL finished) {
               [((GifLoadingView *)view) stopGif];
               [view removeFromSuperview];
//            }];
        }
    }
    
}
- (void)stopGif
{
    [_timer invalidate];
    _timer = nil;
}
- (void)dealloc{
    CFRelease(_gif);
}

static void dispatch_main_after(NSTimeInterval delay, void (^block)(void))
{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        block();
    });
}

总结

简要总结一些三个方法的利弊:

  1. UIImageView采用帧动画将图片一张张显示,这个方法可以调节播放次数和速度但图片过多过大内存会很有压力。另外在保证播放的动画清晰和时长的情况下.gif文件大小会远小于多张.png图片的大小。

  2. UIWebView实现播放gif特别简单直接,如果你只想单纯的播放一下建议使用此方法。弊端就是只能循环播放~~~(>_<)~~~,无法控制它的暂停和其他操作。

  3. 使用第三方播放gif动画集合了第一种方法好处你可以对动画进行一系列操作,在.gif文件比较大的情况下建议使用。(个人喜欢使用此方法)。


最后

我的第二次(写文章)就这么完了。以上很多观点为自己的个人看法不喜勿喷,当然喷了也没事。最后感谢那些能看完小爷这篇文章的小伙伴们,希望能够帮助到你们。( _ )/~~拜拜。

上一篇下一篇

猜你喜欢

热点阅读