dontWatchMyProfile
dontWatchMyProfile

Reputation: 46310

Is setAnimationBeginsFromCurrentState=YES not working in iOS 5 or on the iPad?

My animations don't pick up from current state while in-flight when another kicks in, even though all my animation blocks are configured with:

setAnimationBeginsFromCurrentState=YES

The same is true for block-based animations (the new method since iOS 4), with the UIViewAnimationOptionBeginFromCurrentState option set.

On all my older devices this works perfectly. On iOS 5 and the iPad Simulator it doesn't. Is there a workaround?

(Note: It seems to work on all devices tested. Just not the simulator.)

Here's an example which doesn't work in the 4.3 or 5.0 iPad Simulator:

[UIView animateWithDuration:0.5 
                      delay:1.0f 
                    options:UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState | 
 UIViewAnimationOptionOverrideInheritedDuration | UIViewAnimationOptionOverrideInheritedCurve 
                 animations:^{
                     self.layer.transform = CATransform3DScale(CATransform3DIdentity, 0.5f, 0.5f, 1.0f);
                 }  
                 completion:^(BOOL finished) {
                    [self performSelector:@selector(finishedScaling)];
                 }];

Another animation starts setting the transform scale to 0.1, 0.1 (= very small). While in-flight, this animation kicks in and attempts to bring it back to 0.5, 0.5. When kicking in, the previously kicked off animation ends suddenly with 0.1, 0.1 (= very small). Then scales back up from 0.1 to 0.5. Shouldn't happen. Maybe a bad options combination?

Upvotes: 1

Views: 3075

Answers (2)

matt
matt

Reputation: 534950

You are saying self.layer.transform = in a view animation block. A view animation block is for animating a view. You do this by setting a view's animatable properties - not a layer's animatable properties.

Furthermore, if self is a view, then self.layer.transform is not implicitly animatable. You cannot implicitly animate (i.e. by setting a property) the underlying layer of a view. The layer will always just jump to the new value when you say self.layer.transform =.

So the solution is to say self.transform = (if self is a view), or else don't use block-based animation at all - use Core Animation (e.g. CABasicAnimation) to animate the layer.

Upvotes: 2

matt
matt

Reputation: 534950

Here is an example that works:

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationDuration:1];
        CGPoint p = v.center;
        p.x += 100;
        v.center = p;
        [UIView commitAnimations];

        [UIView beginAnimations:nil context:NULL];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:1];
        CGPoint p2 = v.center;
        p2.y = 0; // and try changing x to y
        v.center = p2;
        [UIView commitAnimations];

With setAnimationBeginsFromCurrentState:YES, the two animations work together, changing the x and y position of the view together. Without it, the first animation is expressed as a "jump" to the right before the second animation begins. So I would say that setAnimationBeginsFromCurrentState:YES is still doing its job correctly. It works the same way on iPad simulator as everywhere else. So there's a counterexample.

Can you, as requested by another comment, actually display the code that isn't working? (You have displayed example code for a second animation but not the first animation, so it's impossible to test.)

Upvotes: 0

Related Questions