Delay in key frame animation when running first time

744 Views Asked by At

I am using key frame animation to animate a sequence of images. But when I run it for the first time there is a delay before animation begins. After that it runs smoothly. I tried force loading all images. It reduced delay but it is still visible. How can I further reduce the delay.

4

There are 4 best solutions below

1
On

Consider pre-loading your images in a NSArray. Your delay is most likely caused by the fact that it first has to load the images.

So , basically , let's say you have img1.png , img2.png , etc up to img10.png:

//do this before your keyframe animation.

NSMutableArray *frames = [NSMutableArray array];
for(int i = 1 ; i <= 10 ; i++)
    [frames addObject:[UIImage imageNamed:[NSString stringWithFormat:@"img%d.png" , i]]];

//now use this array for the animation

Hope this helps. Cheers!

0
On

Apple is notorious for using "lazy" loading techniques, and its quite possible that putting an image retrieved from "[UIImage imageNamed:]" does not in fact create a cached bitmap, just the receipt to create it.

If all else fails try a brute force approach: force the system to render it by rendering the image in a context you then just throw away.

CGSize bigSize; // MAX width and height of your images

UIGraphicsBeginImageContextWithOptions(bigSize, YES, 0);
CGContextRef context = UIGraphicsGetCurrentContext();

for(UIImage *image in arrayOfImages) {
    CGContextDrawImage(context, (CGRect){ {0,0}, image.size }, [image CGImage]);
}
UIGraphicsEndImageContext();

Now you not only have a reference to the images, but they have been forced to render, and so hopefully the system keeps that internal bitmap around. Should be an easy test for you to make.

0
On

I had this problem recently and solved it by 'prerunning' the animation as early as possible with a duration of 0 and not removing it on completion. By the time I actually want to run it, the whole sequence is loaded and smooth

let animation: CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "contents")
    animation.calculationMode = kCAAnimationDiscrete
    animation.duration = 0
    animation.values = spritesArray
    animation.repeatCount = 1
    animation.removedOnCompletion = false
    animation.fillMode = kCAFillModeForwards
    layer.addAnimation(animation, forKey: "animateIn")

In my case I actually had split the sequence into 2 separate keyframe animations for intro/outro and the outro was always stalling before starting. Preloading the whole thing first in a 0 duration keyframe animation prevented that.

0
On

This code is to swift 2.2!

Try to put a final image of you want before the animations end.

It's more like:

// the animation key is for retrive the informations about the array images
func animation(cicleTime:Int, withDuration: Double, animationKey:String){

    var images = [UIImage]()


    // get all images for animation
    for i in 0...cicleTime {
        let fileName = String(format: "image%d",i)
        let image = UIImage(named: fileName)

        images.append(image!)
    }

    let animation = CAKeyframeAnimation(keyPath: "contents")

    animation.setValue(animationKey, forKey: "animationName")

    animation.duration = withDuration
    animation.repeatCount = 1 // times you want to repeat the animation
    animation.values = images.map{$0.CGImage as! AnyObject}
    animation.delegate = self
    images.removeAll(keepCapacity: false)
    YourViewHere.layer.addAnimation(animation, forKey: "contents")

    YourViewHere.image = UIImage(named: "nameOfYourLastImageOfAnimation")
}

Well, this works for me.