最近在研究SceneKit播放Gif,本来打算用UIImageView来播放的,却发现不能播放,在播放是会有一层白色的底色,不知道怎么去除。
再仔细看看API不支持UIView,支持image label和CALayer等,所以就用layer来做动画了。
借鉴网上的方法将gifData数据进行分析,获取到每一帧的图片,和总的时间
CGImageSourceRef source =
CGImageSourceCreateWithData(CFDataRef data, NULL)
size_t count = CGImageSourceGetCount(source);
float allTime = 0;
//存放所有图片
NSMutableArray *imageArray = [[NSMutableArray alloc] init];
NSMutableArray *timeArray = [[NSMutableArray alloc] init];
for (size_t i=0; i<count; i++) {
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(source, i, NULL);
[imageArray addObject:(__bridge UIImage *)imageRef];
CGImageRelease(imageRef);
NSDictionary * info = (__bridge NSDictionary*)CGImageSourceCopyPropertiesAtIndex(source, i, NULL);
NSDictionary *timeDic = [info objectForKey:(__bridge NSString*)kCGImagePropertyGIFDictionary];
CGFloat time = [[timeDic objectForKey:(__bridge NSString*)kCGImagePropertyGIFDelayTime]floatValue];
allTime += time;
[timeArray addObject:[NSNumber numberWithFloat:time]];
}
利用
CAKeyframeAnimation
这个类做动画
添加动画
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:kCAMediaTimingFunctionLinear]];
//设置循环
animation.repeatCount = MAXFLOAT;
//设置播放总时长
animation.duration = totalTime;
animation.removedOnCompletion = NO;//动画结束了禁止删除
animation.fillMode = kCAFillModeForwards;//停在动画结束处
//Layer层添加
[self addAnimation:animation forKey:@"gifAnimation"];
在外部的调用方法:
YXGifLayer *gifLayer = [YXGifLayer layer];
gifLayer.bounds = CGRectMake(0,0,[_wdgetsModel.width integerValue], [_wdgetsModel.height integerValue]);
gifLayer.position = CGPointMake([_wdgetsModel.width integerValue]/2, [_wdgetsModel.height integerValue]/2);
[gifLayer setGifData:data];
SCNPlane *nodeGifPlane = [SCNPlane planeWithWidth:[_wdgetsModel.width integerValue]/100.0 height:[_wdgetsModel.height integerValue]/100.0];
nodeGifPlane.firstMaterial.diffuse.contents = gifLayer;
self.geometry = nodeGifPlane;