SceneKit 播放Gif

最近在研究SceneKit播放Gif,本来打算用UIImageView来播放的,却发现不能播放,在播放是会有一层白色的底色,不知道怎么去除。

再仔细看看API
image

不支持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;

推荐阅读更多精彩内容