Search code examples
iosobjective-cuiviewscreen-orientationcatransform3d

Rotating UIView to device orientation and resizing bounds


In my app I am rotating a UIView to the devices orientation using CMMotionManager. The idea is to keep the UIView level no matter how the user rotates it around its z axis. Image the horizon instrument in airplanes.

This does work pretty well but now I am challenged with a real doozy. I want resize the frame of the UIView when it is rotated so that it always exactly fits into the devices screen AND keeps its aspect ratio. See the awesome drawing below.

Any help here will be very much appreciated!

enter image description here


Solution

  • Assume your device's screen has width W and height H, and the view has height h and width w. You need to scale the frame of the view by a scaling factor to ensure that opposite corners of the view are in contact with the edges of the screen. If you have rotated by an angle theta, then you want to find the largest scaling factor which satisfies:

    scaling_factor * ( h * sin(theta) + w * cos(theta)) <= W ; and

    scaling_factor * ( h * cos(theta) + w * sin(theta)) <= H

    So, re-arrange these:

    scaling_factor <= W / ( h * sin(theta) + w * cos(theta)); and

    scaling_factor <= H / ( h * cos(theta) + w * sin(theta))

    Calculate each of these, and pick the smaller of the two. Either adjust the size of the frame accordingly, or use the CGAffineTransformMakeScale to apply the scaling factor via the view's transform property. You will need to adjust these formulae slightly if theta is negative or more than pi/2, or use abs(theta) for negative theta and (pi - theta) for theta > pi/2.