Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autolayout rotating Wheel

I'm trying to rotate an UIImageView constraint by it's center with CGAffineTransformRotate but the View jitters around while rotating. If I use CATransform3DRotate to rotate it's layer this doesn't happen, but as soon as I edit the Constraints (changing the Constant) the rotated Image jumps away. Has anybody an Idea how to fix this Issue?

This is a Screenshot of the rotated Image that jumped awayenter image description here

like image 919
sensslen Avatar asked Oct 24 '12 07:10

sensslen


2 Answers

Auto layout acts on the frame of your UIView. The frame is calculated from your view's center, bounds, and transform properties. By default view.transform is just the CGAffineTransformIdentity, and in this configuration the frame is a rectangle oriented identically to the superview, with the same width and height as the view's bounds.

However, when you modify the view.transform (or equivalently, the view.layer.transform), as you are doing, then this break the predictable relationship between center, bounds, and frame. For instance, if your transform is a 20 degree rotation, then the frame will no longer have the same width and height as bounds. The frame will now be (I think...) whatever rectangle, oriented identically to the superview, is needed to contain your original rectangle which is now rotated by 20 degrees.

And since auto layout acts on the frame property, it's now likely to produce a layout you don't want.

For example, suppose your view presents a circle within a 10x10 frame rectangle which is top left aligned with the superview via space constraints. Then you rotate it by 45 degrees. A rotated circle looks the same. But now the frame is the smallest rectangle which can contain your original rectangle once rotated, and this smallest rectangle is 10/sqrt(2) x 10/sqrt(2). When auto layout applies top left alignment to this new frame, you will see the your circle shift down and the to the right. Instead of being visually centered at {5,5}, it will now be centered at {5/sqrt(2),5/sqrt(2)}.

I think the remedy for this is either to manually adjust your layout constraint "constant" parameter to correct for the effects of your transform, or else similarly to override alignmentRectForFrame to force auto layout to work on an alignmentRect that is adjusted to compensate for your transform, or else to define your original constraint to bind to the center of your view which might not be affected by the transform.

like image 109
algal Avatar answered Oct 14 '22 15:10

algal


I've just written a little essay on this problem here:

How do I adjust the anchor point of a CALayer, when Auto Layout is being used?

My conclusion there is that autolayout and view transforms do not play well together. I give two solutions: (a) use only constraints that do not fight back against the transform you intend to apply, or (b) take the view completely out of autolayout by using no constraints on it and setting its translatesAutoresizingMask property to YES, so that things work for this view the way they did before autolayout.

like image 34
matt Avatar answered Oct 14 '22 14:10

matt