iOS之GIF动画文件的播放

弘和同
2023-12-01

前言

播放gif动画的方法有多种:
1、将gif图片分解成多张图片使用UIImageView播放
2、webView直接播放.gif文件
3、使用第三方播放

一、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实例

1、GifLoadingView.h

#import <UIKit/UIKit.h>

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

2、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文件比较大的情况下建议使用。(个人喜欢使用此方法)。

 类似资料: