Antonio Sesto
Antonio Sesto

Reputation: 3184

Animating the bounds property of a UIView

According to the Apple documentation available here the bounds property of a UIView can be animated.

In order to programmatically rotate one of my views (in this case from portrait to landscape), I implemented the following code:

 float w = controlsView.bounds.size.width;
 float h = controlsView.bounds.size.height;

 CGAffineTransform T = CGAffineTransformMakeRotation(M_PI/2);

 UIViewContentMode oldContentMode = controlsView.contentMode;
 controlsView.contentMode = UIViewContentModeRedraw;

 [UIView animateWithDuration:1.0 animations:^{
        controlsView.bounds = CGRectMake(0, 0, h, w);
        controlsView.transform = T;
 }];

 controlsView.contentMode = oldContentMode;

I added the two instructions for contentMode because I have read somewhere on StackOverflow that contentMode must be set to that value in order for a UIView to redraw the content while the bounds property is modified (however, in this case it does not affect the behaviour in any way).

The problem of that code is that UIView is not resized with an animation but all at once.

Executing that code, the UIView is first resized (without animation) then rotated with an animation.

How can I animate the resizing?

-- UPDATE --

I tried to combine a scaling and rotating transformation. The UIView rotates and scales in an animation, but at the end its bounds property does not change: even if it has been rotated to a landscape orientation (which should be 568x320 on my iPhone), its width and height stay at the portrait values (320x568). Indeed, the UI controls on the controlsView are deformed (wrong aspect ratio) and appears stretched.

Upvotes: 2

Views: 3875

Answers (3)

CatVsDogs
CatVsDogs

Reputation: 374

Animating your bounds doesn't change its value. It reverts to its original value once the animation ends.

Change the value of the bounds to the final value once the animation is over. I'll solve the trouble.

Upvotes: 0

ihavebeensynthesized
ihavebeensynthesized

Reputation: 156

This worked for me using UIViewAnimationOptions.LayoutSubviews (Swift):

UIView.animateWithDuration(1.0,delay:0.0,
options:UIViewAnimationOptions.LayoutSubviews,
animations:{ () -> Void in
  myView.transform = myRotationTransform
  myView.bounds = myBounds
}, completion: nil)

(no explicit scaling nor changing contentMode)

Upvotes: 3

Rafał Sroka
Rafał Sroka

Reputation: 40048

The problem is that when you set a transform property, all other transforms (bounds) are overwritten. To fix it you have to create one transform that combines scaling and rotating.

Example:

CGAffineTransform scaleTransform = CGAffineTransformMakeScale(0.5, 0.5);

[UIView animateWithDuration:1.0 animations:^
{
    controlsView.transform = CGAffineTransformRotate(scaleTransform, M_PI/2);
}];

You will need to calculate the scaling X and Y values based on the size you want to have at the end of the animations. You might also want to change the anchorPoint property to set a center point used for scaling (controlsView.layer.anchorPoint).

Upvotes: 0

Related Questions