开发者

Sequence of CAAnimations - layer returns to initial position between subsequent calls

I'm trying to create an endless animation of layer rotating slightly to the left, then slightly to the right and back. So I'm animating 10 degress to the left, then 20 to the right, then 10 to the left again. It works great on simulator, but on device the layer "shivers". It appears like it returns to its previous state every time before it starts next animation. I've read that using

animation.removedOnCompletion = NO;

animation.fillMode = kCAFillModeForwards;

helps in such cases, but if I use those, the whole layers just freezes in place after first animation and never moves anywhere.

So here's the code:

- (void) initAnimations {
    float baseValue = [[self.layer valueForKey:@"transform.rotation.z"] floatValue];

    rotateLeft = [[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"] retain];
    rotateLeft.fromValue = [NSNumber numberWithFloat:baseValue];
    rotateLeft.toValue = [NSNumber numberWithFloat:baseValue - DegreesToRadians(10.0f)];
    rotateLeft.duration = 0.4f;
    rotateLeft.removedOnCompletion = NO;
    rotateLeft.fillMode = kCAFillModeForwards;
    rotateLeft.repeatCount = 0;
    rotateLeft.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    rotateLeft.delegate = self;

    rotateRight = [[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"] retain];
    rotateRight.fromValue = [NSNumber numberWithFloat:baseValue - DegreesToRadians(10.0f)];
    rotateRight.toValue = [NSNum开发者_高级运维ber numberWithFloat:baseValue + DegreesToRadians(10.0f)];
    rotateRight.duration = 0.6f;
    rotateRight.removedOnCompletion = NO;
    rotateRight.fillMode = kCAFillModeForwards;
    rotateRight.repeatCount = 0;
    rotateRight.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    rotateRight.delegate = self;

    rotateRestore = [[CABasicAnimation animationWithKeyPath:@"transform.rotation.z"] retain];
    rotateRestore.fromValue = [NSNumber numberWithFloat:baseValue + DegreesToRadians(10.0f)];
    rotateRestore.toValue = [NSNumber numberWithFloat:baseValue];
    rotateRestore.duration = 0.3f;
    rotateRestore.removedOnCompletion = NO;
    rotateRestore.fillMode = kCAFillModeForwards;
    rotateRestore.repeatCount = 0;
    rotateRestore.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    rotateRestore.delegate = self;
}

- (void) beginAnimations {
    if (animationsRunning)
        return;

    [self.layer addAnimation:rotateLeft forKey:nil];
}

- (void)animationDidStart:(CAAnimation *)theAnimation {

}

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
    [self.layer removeAllAnimations];
    if (self.superview == nil) {
        rotateLeft.delegate = nil;
        rotateRight.delegate = nil;
        rotateRestore.delegate = nil;
        return;
    }

    float dt;
    if (step == 0) {
        dt = 0.7f + (float)(random() % 3) / 10.0f;
    } else {
        dt = 0.4f + (float)(random() % 3) / 10.0f;
    }

    CABasicAnimation* nextAnimation = nil;
    if (step == 0) {
        nextAnimation = rotateRight;
    } else if (step == 1) {
        nextAnimation = rotateRestore;
    } else if (step == 2) {
        nextAnimation = rotateLeft;
    }

    nextAnimation.duration = dt;
    [self.layer addAnimation:nextAnimation forKey:nil];

    step++;
    if (step == 3)
        step = 0;
}

Why isn't it working? I think I've already tried all removedOnCompletion / fillMode combinations and nothing seems to help =(

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜