给原生的 UIImageView 添加类别来支持 GIF 播放

本文介绍了一种自定义UIImageView类的方法,用于加载并播放GIF动画。文章详细讲解了如何解析GIF文件以获取其帧信息,并使用Core Animation创建关键帧动画实现连续播放效果。

1.新建一个 UIImageView 的类别

2.解析 GIF ,获得 GIF 的信息

 
#pragma mark -- 解析 DGIF
-(void)gifWithUrl:(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 array];
    //存放每一帧播放的时间
    NSMutableArray *timeArray = [NSMutableArray array];
    //存放每张图片的宽度(一般在一个 gif 文件中,所有文件的尺寸都一样)
    NSMutableArray *widthArray = [NSMutableArray array];
    //存放每张图片的高度
    NSMutableArray * heightArray = [NSMutableArray array];
    //遍历
    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);
        NSLog(@"%@",info);
        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);
}


3.加载 GIF

timingFunction: 控制动画运行的节奏
  • kCAMediaTimingFunctionLinear(线性):匀速,给你一个相对静态的感觉
  • kCAMediaTimingFunctionEaseIn(渐进):动画缓慢进入,然后加速离开
  • kCAMediaTimingFunctionEaseOut(渐出):动画全速进入,然后减速的到达目的地
  • kCAMediaTimingFunctionEaseInEaseOut(渐进渐出):动画缓慢的进入,中间加速,然后减速的到达目的地。这个是默认的动画行为
 
#pragma mark -- 加载 GIF
- (void)cc_setImage:(NSURL *)imageUrl {
    __weak id _self = self;
    [self gifWithUrl: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:kCAMediaTimingFunctionEaseInEaseOut]];
        //设置循环
        animation.repeatCount= MAXFLOAT;
        //设置播放总时长
        animation.duration = totalTime;
        //Layer层添加
        [[(UIImageView *)_self layer]addAnimation:animation forKey:@"gifAnimation"];
    }];
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值