2
votes

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.

3
Why not use a scale and rotate transform? - Wain

3 Answers

2
votes

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)

0
votes

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).

0
votes

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.