views:

77

answers:

1

Hi,

I have a problem I don't understand regarding UIViews and Core Animation. Here's what I want to do:

  • A small view is presented above a bigger view by putting it as one of its subviews.
  • When I click a button inside this view, the view should minimize and move to a specified CGRect.
  • Then the view is removed from its superview.

The first time I present, minimize-and-move and remove the view, everything works fine. But when I present the view again, it displays at the modified position (even though it's supposed to be set at the original position by a call to theView.frame = CGRectMake(600.0, 160.0, 339.0, 327.0);), while all the different responder elements (buttons, textviews, etc.) contained in the view act as if they were at the original position. It's like the view and the layer gets dissynchronized by the animation, and I do not know how to get them back in sync.

Having something like self.view.layer.frame = CGRectMake(600.0, 160.0, 339.0, 327.0); does not get anything right.

My minimize-and-move animation code is given below:

    [CATransaction flush];
    CABasicAnimation *scale, *translateX, *translateY; 
    CAAnimationGroup *group = [CAAnimationGroup animation]; 
    group.delegate = delegate; 
    group.duration = duration; 

    scale = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; 
    translateX = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"]; 
    translateY = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"]; 

    scale.toValue = [NSNumber numberWithFloat:0.13];
    translateX.toValue = [NSNumber numberWithFloat:137.0];
    translateY.toValue = [NSNumber numberWithFloat:-290.0];

    group.animations = [NSArray arrayWithObjects: scale, translateX, translateY, nil];
    group.fillMode = kCAFillModeForwards; 
    group.removedOnCompletion = NO;

    [theView.layer addAnimation:group forKey:@"MyAnimation"];

How to get the layer back to the view after the animation?

A: 

What happens if you remove these two lines?

group.fillMode = kCAFillModeForwards; 
group.removedOnCompletion = NO;

What you are telling core animation with those lines is that you want it to continue to display in the forward (final) state of the animation. Meanwhile, you didn't actually set the transform on the layer to have the properties you used for the animation. This would make things appear to be out of sync.

Now, the issue you're going to run into is that removing those lines will cause your transforms to revert back to the starting state when the animation has completed. What you need to do is actually set the transforms on the layer in order for them to hold their position when the animation completes.

Another option is to leave the two lines in and then actually explicitly remove the animation from the layer instead of setting the layer frame as you mentioned when you are ready to revert back to the original state. You do this with:

[theView.layer removeAnimationForKey:@"MyAnimation"];

The -removedOnCompletion property told the layer not to remove the animation when it finished. Now you can explicitly remove it and it should revert back.

HTH.

Matt Long
Wow, that `removeAnimationForKey:` was exactly what was missing in my code. Thanks, it works great now!
KPM