3

Is it possible to set the transform identity to the current transformed state? My concern is with using auto layout and that once a transformation is applied the frame is now undefined. This is all just an abstract thought process and might not actually be an issue.

Let's say I apply a CGAffineTransformMakeScale(1,-1) to flip a UIView that is a subView of some superView. Now that I have applied a transformation to the subView the frame: now becomes undefined so how is that going to affect the size and placement of the subView in the superView if I resize the superView?

My thought process tells me that if I can set "CGAffineTransformIdentity" to the current transformed state (for example after flipping or rotating) that any auto layout I've set up will be handled correctly but if this is not set i will not get appropriate auto layout handling.

So do I need to worry about the frame: being undefined or will the auto layout use the bounds: of the transformed view?

Old Name
  • 273
  • 1
  • 3
  • 13

1 Answers1

6

Good question. You're correct that the frame of a UIView becomes undefined after applying a transform that is not equal to CGAffineTransformIdentity:

…if the transform property contains a non-identity transform, the value of the frame property is undefined and should not be modified. In that case, you can reposition the view using the center property and adjust the size using the bounds property instead.

However, you may not be aware that Auto Layout does not actually use the frame of a view to align it, but instead uses the "alignment rect" of the view. The alignment rect for a view is retrieved using alignmentRectForFrame:.

The docs note that

The default implementation [of alignmentRectForFrame:] returns the view’s frame modified by the view’s alignmentRectInsets.

and elaborate, saying

Most custom views can override alignmentRectInsets to specify the location of their content within their frame. Custom views that require arbitrary transformations can override alignmentRectForFrame: and frameForAlignmentRect: to describe the location of their content. These two methods must always be inverses of each other.

So, to answer your question,

So do I need to worry about the frame: being undefined or will the auto layout use the bounds: of the transformed view?

the answer is, in the general case, you will have to implement alignmentRectForFrame: and frameForAlignmentRect:, and be sure that they are inverses of each other.

This is a more thorough treatment of the issue, and I recommend you take a look.

Community
  • 1
  • 1
ravron
  • 11,014
  • 2
  • 39
  • 66
  • Thanks for the great explanation. Your reference to more information also answered some other questions I had and solutions I had considered such as transforming the `CALayer` instead of the `UIView`, adding another childView to the subView, and whether iOS 8 is going to change the way this is handled (still unsure of if and how it does at this point though). Thanks again! – Old Name Jul 25 '14 at 22:03