iOS-播放gif动画文件(OC方法)
iOS-.gif动画文件的播放
前言
播放gif动画的方法有多种:
- 将gif图片分解成多张图片使用UIImageView播放
- webView直接播放.gif文件
- 使用第三方播放
本文主要介绍的是这三种方法播放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.framework和MobileCoreServices.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();
});
}
总结
简要总结一些三个方法的利弊:
-
UIImageView采用帧动画将图片一张张显示,这个方法可以调节播放次数和速度但图片过多过大内存会很有压力。另外在保证播放的动画清晰和时长的情况下.gif文件大小会远小于多张.png图片的大小。
-
UIWebView实现播放gif特别简单直接,如果你只想单纯的播放一下建议使用此方法。弊端就是只能循环播放~~~(>_<)~~~,无法控制它的暂停和其他操作。
-
使用第三方播放gif动画集合了第一种方法好处你可以对动画进行一系列操作,在.gif文件比较大的情况下建议使用。(个人喜欢使用此方法)。
最后
我的第二次(写文章)就这么完了。以上很多观点为自己的个人看法不喜勿喷,当然喷了也没事。最后感谢那些能看完小爷这篇文章的小伙伴们,希望能够帮助到你们。( _ )/~~拜拜。