示例代码

///////////////////////第一种///////////////////////

//
//  GifView.h
//  GIFViewer
//
//  Created by xToucher04 on 11-11-9.
//  Copyright 2011 Toucher. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <ImageIO/ImageIO.h>

@interface GifView : UIView {
    CGImageSourceRef gif;
    NSDictionary *gifProperties;
    size_t index;
    size_t count;
    NSTimer *timer;
}

- (id)initWithFrame:(CGRect)frame filePath:(NSString *)_filePath;

- (id)initWithFrame:(CGRect)frame data:(NSData *)_data;

@end

//例子
////
////  ViewController.m
////  播放动态图片
////
//
//#import "ViewController.h"
//#import "GifView.h"
//
//@interface ViewController ()
//
//@end
//
//@implementation ViewController
//
//- (void)viewDidLoad {
//    [super viewDidLoad];
//    //第一种 用UIImageView中的动画数组播放动画
//    [self showGifImageMethodOne];
//    //第二种 用UIWebView显示
//    [self showGifImageMethodTwo];
//    //第三种 用第三方GifView显示本地图片
//    [self showGifImageMethodThree];
//    //用第三方显示从网络获取的动态图片
//    [self showGifImageMethodFour];
//}
//
//#pragma mark 播放动态图片方式1 UIImageView
//-(void)showGifImageMethodOne {
//    //第一种 用UIImageView中的动画数组播放动画
//    //创建UIImageView,添加到界面
//    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 100, 100)];
//    [self.view addSubview:imageView];
//    //创建一个数组,数组中按顺序添加要播放的图片(图片为静态的图片)
//    NSMutableArray *imgArray = [NSMutableArray array];
//    for (int i=1; i<7; i++) {
//        UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"clock%02d.png",i]];
//        [imgArray addObject:image];
//    }
//    //把存有UIImage的数组赋给动画图片数组
//    imageView.animationImages = imgArray;
//    //设置执行一次完整动画的时长
//    imageView.animationDuration = 6*0.15;
//    //动画重复次数 (0为重复播放)
//    imageView.animationRepeatCount = 0;
//    //开始播放动画
//    [imageView startAnimating];
//    //停止播放动画  - (void)stopAnimating;
//    //判断是否正在执行动画  - (BOOL)isAnimating;
//}
//
//#pragma mark 播放动态图片方式2 UIWebView
//-(void)showGifImageMethodTwo {
//    //第二种 用UIWebView显示
//    //得到图片的路径
//    NSString *path = [[NSBundle mainBundle] pathForResource:@"happy" ofType:@"gif"];
//    //将图片转为NSData
//    NSData *gifData = [NSData dataWithContentsOfFile:path];
//    //创建一个webView,添加到界面
//    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 150, 200, 200)];
//    [self.view addSubview:webView];
//    //自动调整尺寸
//    webView.scalesPageToFit = YES;
//    //禁止滚动
//    webView.scrollView.scrollEnabled = NO;
//    //设置透明效果
//    webView.backgroundColor = [UIColor clearColor];
//    webView.opaque = 0;
//    //加载数据
//    [webView loadData:gifData MIMEType:@"image/gif" textEncodingName:nil baseURL:nil];
//}
//
//#pragma mark 播放动态图片方式3 第三方显示本地动态图片
//-(void)showGifImageMethodThree {
//    //方式一
//    //将图片转为NSData数据
//    NSData *localData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"bird" ofType:@"gif"]];
//    //创建一个第三方的View显示图片
//    GifView *dataView = [[GifView alloc] initWithFrame:CGRectMake(0, 300, 200, 100) data:localData];
//    [self.view addSubview:dataView];
//    //方式二
//    //得到图片的路径
//    NSString *path = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"gif"];
//    GifView *dataView2 = [[GifView alloc] initWithFrame:CGRectMake(200, 300, 150, 100) filePath:path];
//    [self.view addSubview:dataView2];
//}
//
//#pragma mark 播放动态图片方式3 第三方显示从网络获取的动态图片
//-(void)showGifImageMethodFour {
//    // 网络图片
//    NSData *urlData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://pic19.nipic.com/20120222/8072717_124734762000_2.gif"]];
//    //创建一个第三方的View显示图片
//    GifView *dataViewWeb = [[GifView alloc] initWithFrame:CGRectMake(20, 420, 280, 100) data:urlData];
//    [self.view addSubview:dataViewWeb];
//}
//
//- (void)didReceiveMemoryWarning {
//    [super didReceiveMemoryWarning];
//}
//
//@end

////////////////////////////////

//
//  GifView.m
//  GIFViewer
//
//  Created by xToucher04 on 11-11-9.
//  Copyright 2011 Toucher. All rights reserved.
//

#import "GifView.h"
#import <QuartzCore/QuartzCore.h>

@implementation GifView

- (id)initWithFrame:(CGRect)frame filePath:(NSString *)_filePath {
    self = [super initWithFrame:frame];
    if (self) {
        gifProperties = [[NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount]
                                                     forKey:(NSString *)kCGImagePropertyGIFDictionary] retain];
        gif = CGImageSourceCreateWithURL((CFURLRef)[NSURL fileURLWithPath:_filePath], (CFDictionaryRef)gifProperties);
        count =CGImageSourceGetCount(gif);
        timer = [NSTimer scheduledTimerWithTimeInterval:0.12 target:self selector:@selector(play) userInfo:nil repeats:YES];
        [timer fire];
    }
    return self;
}

- (id)initWithFrame:(CGRect)frame data:(NSData *)_data{
    self = [super initWithFrame:frame];
    if (self && _data) {
        gifProperties = [[NSDictionary dictionaryWithObject:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:0] forKey:(NSString *)kCGImagePropertyGIFLoopCount]
                                                     forKey:(NSString *)kCGImagePropertyGIFDictionary] retain];
       gif = CGImageSourceCreateWithData((CFDataRef)_data, (CFDictionaryRef)gifProperties);
        count =CGImageSourceGetCount(gif);
        timer = [NSTimer scheduledTimerWithTimeInterval:0.12 target:self selector:@selector(play) userInfo:nil repeats:YES];
        [timer fire];
    }
    return self;
}

-(void)play {
    index ++;
    index = index % count;
    CGImageRef ref = CGImageSourceCreateImageAtIndex(gif, index, (CFDictionaryRef)gifProperties);
    self.layer.contents = (id)ref;
    CFRelease(ref);
}

-(void)removeFromSuperview {
    NSLog(@"removeFromSuperview");
    [timer invalidate];
    timer = nil;
    [super removeFromSuperview];
}
- (void)dealloc {
    NSLog(@"dealloc");
    CFRelease(gif);
    [gifProperties release];
    [super dealloc];
}
@end

///////////////////////第二种///////////////////////

//
//  UIImageView+Gif.h
//  DemoTest1
//
//  Created by 李鹏超 on 16/8/11.
//  Copyright © 2016年 李鹏超. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface UIImageView (Gif)

-(void)getGifImageWithUrk:(NSURL *)url
               returnData:(void(^)(NSArray<UIImage *> * imageArray,
                                   NSArray<NSNumber *>*timeArray,
                                   CGFloat totalTime,
                                   NSArray<NSNumber *>* widths,
                                   NSArray<NSNumber *>* heights))dataBlock;

-(void)yh_setImage:(NSURL *)imageUrl;

@end

//使用例子
//使用代码示例如下:

//UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 50 , 320, 100)];
//NSURL * url = [[NSURL alloc]initFileURLWithPath:[[NSBundle mainBundle] pathForResource:@"1-1.gif" ofType:nil]];
//    [imageView yh_setImage:url];
//    [imageView getGifImageWithUrk:url returnData:^(NSArray<UIImage *> *imageArray, NSArray<NSNumber *> *timeArray, CGFloat totalTime, NSArray<NSNumber *> *widths, NSArray<NSNumber *> *heights) {
//
//    }];

//SDWebImage中的方法例子
//  self.loadingImageView.image = [UIImage sd_animatedGIFWithData:imageData];
//#import <UIKit/UIKit.h>
//
//@interface UIImage (GIF)
//
//+ (UIImage *)sd_animatedGIFNamed:(NSString *)name;
//
//+ (UIImage *)sd_animatedGIFWithData:(NSData *)data;
//
//- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size;
//
//@end

//getHUb -- 第三方 FLAnimatedImage

////////////////////////////

//
//  UIImageView+Gif.m
//  DemoTest1
//
//  Created by 李鹏超 on 16/8/11.
//  Copyright © 2016年 李鹏超. All rights reserved.
//

#import "UIImageView+Gif.h"
#import <ImageIO/ImageIO.h>

@implementation UIImageView (Gif)

//解析gif文件数据的方法 block中会将解析的数据传递出来
-(void)getGifImageWithUrk:(NSURL *)url
               returnData:(void(^)(NSArray<UIImage *> * imageArray,
                                   NSArray<NSNumber *>*timeArray,
                                   CGFloat totalTime,
                                   NSArray<NSNumber *>* widths,
                                   NSArray<NSNumber *>* heights))dataBlock {
    //通过文件的url来将gif文件读取为图片数据引用
    CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, NULL);
    //获取gif文件中图片的个数
    size_t count = CGImageSourceGetCount(source);
    //定义一个变量记录gif播放一轮的时间
    float allTime=0;
    //存放所有图片
    NSMutableArray * imageArray = [[NSMutableArray alloc]init];
    //存放每一帧播放的时间
    NSMutableArray * timeArray = [[NSMutableArray alloc]init];
    //存放每张图片的宽度 (一般在一个gif文件中,所有图片尺寸都会一样)
    NSMutableArray * widthArray = [[NSMutableArray alloc]init];
    //存放每张图片的高度
    NSMutableArray * heightArray = [[NSMutableArray alloc]init];
    //遍历
    for (size_t i=0; i<count; i++) {
        CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
        [imageArray addObject:(__bridge UIImage *)(image)];
        CGImageRelease(image);
        //获取图片信息
        NSDictionary * info = (__bridge NSDictionary*)CGImageSourceCopyPropertiesAtIndex(source, i, NULL);
        CGFloat width = [[info objectForKey:(__bridge NSString *)kCGImagePropertyPixelWidth] floatValue];
        CGFloat height = [[info objectForKey:(__bridge NSString *)kCGImagePropertyPixelHeight] floatValue];
        [widthArray addObject:[NSNumber numberWithFloat:width]];
        [heightArray addObject:[NSNumber numberWithFloat:height]];
        NSDictionary * timeDic = [info objectForKey:(__bridge NSString *)kCGImagePropertyGIFDictionary];
        CGFloat time = [[timeDic objectForKey:(__bridge NSString *)kCGImagePropertyGIFDelayTime]floatValue];
        allTime+=time;
        [timeArray addObject:[NSNumber numberWithFloat:time]];
    }
    dataBlock(imageArray,timeArray,allTime,widthArray,heightArray);
}

//为UIImageView添加一个设置gif图内容的方法:

-(void)yh_setImage:(NSURL *)imageUrl{
    __weak id __self = self;
    [self getGifImageWithUrk:imageUrl returnData:^(NSArray<UIImage *> *imageArray, NSArray<NSNumber *> *timeArray, CGFloat totalTime, NSArray<NSNumber *> *widths, NSArray<NSNumber *> *heights) {
        //添加帧动画
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"contents"];
        NSMutableArray * times = [[NSMutableArray alloc]init];
        float currentTime = 0;
        //设置每一帧的时间占比
        for (int i=0; i<imageArray.count; i++) {
            [times addObject:[NSNumber numberWithFloat:currentTime/totalTime]];
            currentTime+=[timeArray[i] floatValue];
        }
        [animation setKeyTimes:times];
        [animation setValues:imageArray];
        [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
        //设置循环
        animation.repeatCount= MAXFLOAT;
        //设置播放总时长
        animation.duration = totalTime;
        //Layer层添加
        [[(UIImageView *)__self layer]addAnimation:animation forKey:@"gifAnimation"];
    }];
}

@end

iOS 自定义方法 - 播放GIF的更多相关文章

  1. iOS音乐播放器相关

    iOS音乐播放器框架主要有两大类:AvPlayer.AvaudioPlayer AvPlayer 能播放本地及网络歌曲 AvaudioPlayer 能播放本地歌曲.有相关代理方法(其实也可以播放网络歌 ...

  2. 一个功能齐全的IOS音乐播放器应用源码

    该源码是在ios教程网拿过来的,一个不错的IOS音乐播放器应用源码,这个是我当时进公司时 我用了一晚上写的  图片都是在别的地方扒的,主要是歌词同步,及上一曲,下一曲,功能齐全了 ,大家可以学习一下吧 ...

  3. IOS 音频播放

    iOS音频播放 (一):概述 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改我也因此对于iOS下的音频播放实现有了一定的研究.写这个系列的博客目的一方面希望能够抛砖 ...

  4. iOS音频播放(一):概述

    (本文转自码农人生) 前言 从事音乐相关的app开发也已经有一段时日了,在这过程中app的播放器几经修改,我也因此对于iOS下的音频播放实现有了一定的研究.写这个 系列的博客目的一方面希望能够抛砖引玉 ...

  5. iOS音频播放、录音、视频播放、拍照、视频录制

    随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...

  6. iOS AVAudioPlayer播放音频时声音太小

    iOS AVAudioPlayer播放音频时声音太小 //引入AVFoundation类库,设置播放模式就可以了 do { try AVAudioSession.sharedInstance().ov ...

  7. iOS直播-播放基于RTMP协议的视频

    iOS直播-播放基于RTMP协议的视频 流媒体协议介绍 1. 伪流媒体: 渐进式下载 : 边下边存, 文件会保存 使用http协议,也能够实现视频播放, 也能快进快退等, 体验上跟流媒体很像. 优酷, ...

  8. iOS音频播放 (二):AudioSession 转

    原文出处 :http://msching.github.io/blog/2014/07/08/audio-in-ios-2/ 前言 本篇为<iOS音频播放>系列的第二篇. 在实施前一篇中所 ...

  9. iOS音频播放之AudioQueue(一):播放本地音乐

    AudioQueue简单介绍 AudioStreamer说明 AudioQueue具体解释 AudioQueue工作原理 AudioQueue主要接口 AudioQueueNewOutput Audi ...

随机推荐

  1. 【初码干货】【Azure系列】1、再次感受Azure,体验Windows Server 2016并部署BlogEngine.NET

    上个月末,在某人的建议下,重新注册了一个1元试用账户(包含1个月期限的1500元订阅),并充值了1000元转为了正式账户,相当于1000元得到了2500的订阅,于是又一次开启了Azure之旅. 在这不 ...

  2. 《高性能javascript》一书要点和延伸(下)

    第六章 快速响应的用户界面 本章开篇介绍了浏览器UI线程的概念,我也突然想到一个小例子,这是写css3动画的朋友都经常会碰到的一个问题: <head> <meta charset=& ...

  3. 扑面而来的碎片--图片3D炸裂效果初体验

    之前逛园子的时候看到 ChokCoco 的爆炸效果作品:[BOOM]一款有趣的Javascript动画效果 (大神英文有没有拼错呀←.←),觉得蛮有意思的,效果如下: 不过觉得这个爆炸效果还是偏软了一 ...

  4. Leetcode 笔记 35 - Valid Soduko

    题目链接:Valid Sudoku | LeetCode OJ Determine if a Sudoku is valid, according to: Sudoku Puzzles - The R ...

  5. [Intel Edison开发板] 05、Edison开发基于MRAA实现IO控制,特别是UART通信

    一.前言 下面是本系列文章的前几篇: [Intel Edison开发板] 01.Edison开发板性能简述 [Intel Edison开发板] 02.Edison开发板入门 [Intel Edison ...

  6. Android开发学习之路-关于Exception

    Exception在Java中是表示异常的一个类.它是Throwable的子类. 而Exception的子类RuntimeException是一个特殊的异常类,在代码中不需要对此类进行throw,而是 ...

  7. CI Weekly #9 | 揭秘阿里 Docker 化实践之路

    2017年悄然而至,对 flow.ci 你有什么新的期待呢?新的一年,flow.ci会越来越强大好用,希望继续得到你的支持与反馈.最近,我们做了如下的「功能优化」与「问题修复」,看看有没有你想要的: ...

  8. JavaScript随笔2

    JavaScript的组成:ECMA.DOM.BOM闭包,子函数可以使用父函数的局部变量 函数:arguments是个参数数组oDiv.style.width:只能操作行间的样式.在IE下oDiv.c ...

  9. 【.net 深呼吸】自定义缓存配置(非Web项目)

    在前一篇烂文中,老周简单讲述了非Web应用的缓存技术的基本用法.其实嘛,使用系统默认方案已经满足我们的需求了,不过,如果你真想自己来配置缓存,也是可以的. 缓存的自定义配置可以有两种方案,一种是用代码 ...

  10. 为WLW开发Latex公式插件

    WLW是写博客的利器,支持离线.格式排版等,而且拥有众多的插件.博客园推荐了代码插入插件,但是没有提供WLW的公式编译插件.目前我的一般做法是:先在Word下使用MathType编辑好公式,然后将公式 ...