iOS-播放gif動畫文件(OC方法)

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文件比較大的情況下建議使用。(個人喜歡使用此方法)。


最后

我的第二次(寫文章)就這么完了。以上很多觀點為自己的個人看法不喜勿噴,當然噴了也沒事。最后感謝那些能看完小爺這篇文章的小伙伴們,希望能夠幫助到你們。( _ )/~~拜拜。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容