10

Transforming a UIView affects its frame. Transforming a UIView's layer also affects the views frame in the same way. So scaling a view's layer, scales the frame. I'm trying to understand why transforms to the layer affect the views frame (even when view.layer.masksToBounds = NO is set).

UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
NSLog(@"Before: %@", NSStringFromCGRect(view.frame));
// Output: {{0, 0}, {50, 50}}

// View transform applied
view.transform = CGAffineTransformMakeScale(2, 2);
NSLog(@"%@", NSStringFromCGRect(view.frame));
// Output: {{-25, -25}, {100, 100}}


// Layer transform applied
view.transform = CGAffineTransformIdentity;
view.layer.transform = CATransform3DMakeScale(2, 2, 1);
NSLog(@"%@", NSStringFromCGRect(view.frame));
// Output: {{-25, -25}, {100, 100}}
Daniyar
  • 2,975
  • 2
  • 26
  • 39
Warpling
  • 2,024
  • 2
  • 22
  • 38
  • 1
    You shouldn't look at the frame value once you have a transform. From the documentation for the `frame` property on UIView: "WARNING If the `transform` property is not the identity transform, the value of this property is undefined and therefore should be ignored." – David Rönnqvist Apr 23 '15 at 12:49
  • Thank you @DavidRönnqvist. This is exactly the kind of explanation I needed to hear. If you make this an answer I will accept it. – Warpling Apr 23 '15 at 18:27

3 Answers3

11

You shouldn't look at the frame value once you have a transform, since it's undefined what it contains at that point. This is mentioned in the documentation for the frame property on UIView:

WARNING

If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.

If you need that to modify the frame, you have to do so using the center and bounds properties instead.

Community
  • 1
  • 1
David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
  • This documentation is referring to the `view.transform` property. It doesn't say if `view.layer.transform` affects the frame. But from experimentation, it apparently does. – Glenn Schmidt Jul 09 '16 at 11:32
  • @Glenn Schmidt, a `UIView`'s `transform` and `frame` properties are directed to and from its underlying `CALayer`, so everything should apply equally. – bompf May 02 '18 at 08:41
2

A frame is a very specific thing.

This rectangle defines the size and position of the view in its superview’s coordinate system. You use this rectangle during layout operations to size and position the view.

Transforms applied to a view effect the origin and size of that view in the superview which is why the view's frame changes.

Transforming subviews will effect the frames of the subviews, but not their superview's frame.


It's worth noting that bounds differs from frame in this respect. The bounds of a view is the origin and size of a view within it's own coordinate system. Transforms should not change a view's bounds, because the transform changes the size and placement of the view for external coordinates, but not the view's internal coordinates.

Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • Thanks Jeffery, I know that applying a transform to a view will affect its frame, what I'm trying to understand is why applying a transform to a views layer affects its frame. – Warpling Apr 09 '15 at 03:26
  • From the documentation for the `frame` property on UIView: "WARNING: If the `transform` property is not the identity transform, the value of this property is undefined and therefore should be ignored." – David Rönnqvist Apr 23 '15 at 12:46
1

The frame is a computing property. Basically, it's synthesized from center and bounds.( To know more, please search for anchorPoint of CALayer). What's more, when transform is taken into consideration. The frame will be a bounding box that will cover the original box, even rotation or scale is applied. And the default implementation of hitTest and pointInside will use the final frame, which means you can touch the translated or rotated view normally.

user3349433
  • 480
  • 2
  • 11
  • Strange that the frame is usually explicitly set, but is also a computed property. That makes sense in the context of `hitTest` or `pointInside` though! – Warpling Apr 09 '15 at 03:20