一、簡單介紹
gif動畫是iOS開發中很常用的一個功能,有的是為了顯示加載視頻的過程,更多的是為了顯示一個結果狀態(動畫更直觀)。
那么如何執行gif動畫,方法有很多。(這里只寫一下方法三,前兩種之前都用過)
方法一使用UIWebView來顯示;
方法二使用UIImageView的幀動畫顯示;
方法三使用SDWebImage這個三方框架來顯示。
二、簡單使用
1、顯示gif動畫(三方框架SDWebImage的UIImage+GIF分類)
#import "UIImage+GIF.h" #import "SDWebImageGIFCoder.h" #import "NSImage+WebCache.h" @implementation UIImage (GIF) + (UIImage *)sd_animatedGIFWithData:(NSData *)data { if (!data) { return nil; } return [[SDWebImageGIFCoder sharedCoder] decodedImageWithData:data]; } - (BOOL)isGIF { return (self.images != nil); } @end
//使用 NSData *gifData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"live_sign" ofType:@"gif"]]; UIImage *signSuccessGifImg = [UIImage sd_animatedGIFWithData:gifData]; self.imageView.image = signSuccessGifImg;
2、獲取gif動畫時長
//獲取gif圖片的總時長 - (NSTimeInterval)durationForGifData:(NSData *)data{ //將GIF圖片轉換成對應的圖片源 CGImageSourceRef gifSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); //獲取其中圖片源個數,即由多少幀圖片組成 size_t frameCout = CGImageSourceGetCount(gifSource); //定義數組存儲拆分出來的圖片 NSMutableArray* frames = [[NSMutableArray alloc] init]; NSTimeInterval totalDuration = 0; for (size_t i=0; i<frameCout; i++) { //從GIF圖片中取出源圖片 CGImageRef imageRef = CGImageSourceCreateImageAtIndex(gifSource, i, NULL); //將圖片源轉換成UIimageView能使用的圖片源 UIImage* imageName = [UIImage imageWithCGImage:imageRef]; //將圖片加入數組中 [frames addObject:imageName]; NSTimeInterval duration = [self gifImageDeleyTime:gifSource index:i]; totalDuration += duration; CGImageRelease(imageRef); } //獲取循環次數 NSInteger loopCount;//循環次數 CFDictionaryRef properties = CGImageSourceCopyProperties(gifSource, NULL); if (properties) { CFDictionaryRef gif = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary); if (gif) { CFTypeRef loop = CFDictionaryGetValue(gif, kCGImagePropertyGIFLoopCount); if (loop) { //如果loop == NULL,表示不循環播放,當loopCount == 0時,表示無限循環; CFNumberGetValue(loop, kCFNumberNSIntegerType, &loopCount); }; } } CFRelease(gifSource); return totalDuration; }
//獲取GIF圖片每幀的時長 - (NSTimeInterval)gifImageDeleyTime:(CGImageSourceRef)imageSource index:(NSInteger)index { NSTimeInterval duration = 0; CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, index, NULL); if (imageProperties) { CFDictionaryRef gifProperties; BOOL result = CFDictionaryGetValueIfPresent(imageProperties, kCGImagePropertyGIFDictionary, (const void **)&gifProperties); if (result) { const void *durationValue; if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFUnclampedDelayTime, &durationValue)) { duration = [(__bridge NSNumber *)durationValue doubleValue]; if (duration < 0) { if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFDelayTime, &durationValue)) { duration = [(__bridge NSNumber *)durationValue doubleValue]; } } } } } return duration; }
3、獲取gif動畫執行次數
//獲取gif圖片的循環次數 -(NSInteger)repeatCountForGifData:(NSData *)data{ //將GIF圖片轉換成對應的圖片源 CGImageSourceRef gifSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); //獲取循環次數 NSInteger loopCount = 0;//循環次數 CFDictionaryRef properties = CGImageSourceCopyProperties(gifSource, NULL); if (properties) { CFDictionaryRef gif = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary); if (gif) { CFTypeRef loop = CFDictionaryGetValue(gif, kCGImagePropertyGIFLoopCount); if (loop) { //如果loop == NULL,表示不循環播放,當loopCount == 0時,表示無限循環; CFNumberGetValue(loop, kCFNumberNSIntegerType, &loopCount); }; } } CFRelease(gifSource); return loopCount; }
三、創建分類
#import "UIImageView+GIFProperty.h"

// // UIImageView+GIFProperty.h // YuwenParent // // Created by 夏遠全 on 2019/4/11. // Copyright © 2019年 xiaoshuang. All rights reserved. // #import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface UIImageView (GIFProperty) -(NSTimeInterval)durationForGifData:(NSData *)data;//獲取gif動畫總時長 -(NSInteger)repeatCountForGifData:(NSData *)data; //獲取gif動畫循環總次數 0:表示無限循環 @end NS_ASSUME_NONNULL_END

// // UIImageView+GIFProperty.m // YuwenParent // // Created by 夏遠全 on 2019/4/11. // Copyright © 2019年 xiaoshuang. All rights reserved. // #import "UIImageView+GIFProperty.h" @implementation UIImageView (GIFProperty) //獲取gif圖片的總時長 - (NSTimeInterval)durationForGifData:(NSData *)data{ //將GIF圖片轉換成對應的圖片源 CGImageSourceRef gifSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); //獲取其中圖片源個數,即由多少幀圖片組成 size_t frameCout = CGImageSourceGetCount(gifSource); //定義數組存儲拆分出來的圖片 NSMutableArray* frames = [[NSMutableArray alloc] init]; NSTimeInterval totalDuration = 0; for (size_t i=0; i<frameCout; i++) { //從GIF圖片中取出源圖片 CGImageRef imageRef = CGImageSourceCreateImageAtIndex(gifSource, i, NULL); //將圖片源轉換成UIimageView能使用的圖片源 UIImage* imageName = [UIImage imageWithCGImage:imageRef]; //將圖片加入數組中 [frames addObject:imageName]; NSTimeInterval duration = [self gifImageDeleyTime:gifSource index:i]; totalDuration += duration; CGImageRelease(imageRef); } //獲取循環次數 NSInteger loopCount;//循環次數 CFDictionaryRef properties = CGImageSourceCopyProperties(gifSource, NULL); if (properties) { CFDictionaryRef gif = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary); if (gif) { CFTypeRef loop = CFDictionaryGetValue(gif, kCGImagePropertyGIFLoopCount); if (loop) { //如果loop == NULL,表示不循環播放,當loopCount == 0時,表示無限循環; CFNumberGetValue(loop, kCFNumberNSIntegerType, &loopCount); }; } } CFRelease(gifSource); return totalDuration; } //獲取gif圖片的循環次數 -(NSInteger)repeatCountForGifData:(NSData *)data{ //將GIF圖片轉換成對應的圖片源 CGImageSourceRef gifSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); //獲取循環次數 NSInteger loopCount = 0;//循環次數 CFDictionaryRef properties = CGImageSourceCopyProperties(gifSource, NULL); if (properties) { CFDictionaryRef gif = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary); if (gif) { CFTypeRef loop = CFDictionaryGetValue(gif, kCGImagePropertyGIFLoopCount); if (loop) { //如果loop == NULL,表示不循環播放,當loopCount == 0時,表示無限循環; CFNumberGetValue(loop, kCFNumberNSIntegerType, &loopCount); }; } } CFRelease(gifSource); return loopCount; } //獲取GIF圖片每幀的時長 - (NSTimeInterval)gifImageDeleyTime:(CGImageSourceRef)imageSource index:(NSInteger)index { NSTimeInterval duration = 0; CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, index, NULL); if (imageProperties) { CFDictionaryRef gifProperties; BOOL result = CFDictionaryGetValueIfPresent(imageProperties, kCGImagePropertyGIFDictionary, (const void **)&gifProperties); if (result) { const void *durationValue; if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFUnclampedDelayTime, &durationValue)) { duration = [(__bridge NSNumber *)durationValue doubleValue]; if (duration < 0) { if (CFDictionaryGetValueIfPresent(gifProperties, kCGImagePropertyGIFDelayTime, &durationValue)) { duration = [(__bridge NSNumber *)durationValue doubleValue]; } } } } } return duration; } @end