Benedict Cohen
Benedict Cohen

Reputation: 11920

Is a UIView animation dependant on order of properties being set?

I have encountered something strange with UIView animations. The animation scales a sub view from a rect to fill its parent view:

//update views
CGRect startRect = ...; //A rect in parentView co-ordinates space that childView appears from
UIView *parentView = ...;
UIView *childView = ...;
[parentView addSubview:childView];

//animation start state
childView.alpha = 0;
childView.center = (CGPointMake( CGRectGetMidX(startRect),  CGRectGetMidY(startRect)));
//TODO: set childViews transform and so that it is completely contained with in startRect
childView.transform = CGAffineTransformMakeScale(.25, .25); 

[UIView animateWithDuration:.25 animations:^{
    childView.transform = CGAffineTransformIdentity;        
    childView.alpha = 1;
    childView.frame = parentView.bounds;
}];

The above code works as expected. However, if the animation block is reordered to the following then the animation goes haywire (scales massively and center point is off screen):

[UIView animateWithDuration:.25 animations:^{
    childView.frame = parentView.bounds; //This line was after .alpha
    childView.transform = CGAffineTransformIdentity;        
    childView.alpha = 1;
}];

What's going on here? Why is the order that the properties are set significant to the animation?

Upvotes: 1

Views: 106

Answers (1)

David Rönnqvist
David Rönnqvist

Reputation: 56635

The order of the properties is probably relevant because the frame is undefined when the transform is not the identity transform.

Warning: If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.

From the documentation for frame (on UIView).

This is true for getting the frame value but I believe that it also is true for setting the frame.

I'm almost certain that the changes in your animation block happens on the model of the views layer before they are animated on the presentation of the views layer.

Since you are coming form a state where the transform is a scale, setting the frame is undefined.

In your top example the transform is set to identity before setting the frame, thus it works as expected, but in the second example you set the frame before restoring the transform.

Upvotes: 1

Related Questions