CGAffineTransform changes view.bounds?
Asked Answered
D

1

10

Views have both a frame (coordinates in superview's coordinate system) and bounds (coordinates in own coordinate system) property, but if you transform a view, you should not use or rely on the frame property anymore. If you are using transformations, work with the bounds property only, not the frame property, as transformations are applied to the bounds, but aren't necessarily reflected accurately in frame

http://iphonedevelopment.blogspot.jp/2008/10/demystifying-cgaffinetransform.html

I wanted to see what he means in the above paragraph and printed 'frame' and 'bounds'
And I see only 'frame' is changing during the pinch.

- (IBAction)handlePinch:(UIPinchGestureRecognizer*)recognizer
{
    NSLog(@"scale: %f, velocity: %f", recognizer.scale, recognizer.velocity);
    NSLog(@"Before, frame: %@, bounds: %@", NSStringFromCGRect(recognizer.view.frame), NSStringFromCGRect(recognizer.view.bounds));
    recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
    NSLog(@"After, frame: %@, bounds: %@", NSStringFromCGRect(recognizer.view.frame), NSStringFromCGRect(recognizer.view.bounds));

    recognizer.scale = 1;
}

output:(zomming in)

2012-07-02 14:53:51.458 GestureRec[1264:707] scale: 1.030111, velocity: 0.945660
2012-07-02 14:53:51.466 GestureRec[1264:707] Before, frame: {{0, 124}, {320, 160}}, bounds: {{0, 0}, {320, 160}}
2012-07-02 14:53:51.473 GestureRec[1264:707] After, frame: {{-4.81771, 121.591}, {329.635, 164.818}}, bounds: {{0, 0}, {320, 160}}
2012-07-02 14:53:51.480 GestureRec[1264:707] scale: 1.074539, velocity: 1.889658
2012-07-02 14:53:51.484 GestureRec[1264:707] Before, frame: {{-4.81771, 121.591}, {329.635, 164.818}}, bounds: {{0, 0}, {320, 160}}
2012-07-02 14:53:51.494 GestureRec[1264:707] After, frame: {{-17.103, 115.449}, {354.206, 177.103}}, bounds: {{0, 0}, {320, 160}}
2012-07-02 14:53:51.499 GestureRec[1264:707] scale: 1.000000, velocity: 1.889658
2012-07-02 14:53:51.506 GestureRec[1264:707] Before, frame: {{-17.103, 115.449}, {354.206, 177.103}}, bounds: {{0, 0}, {320, 160}}
2012-07-02 14:53:51.510 GestureRec[1264:707] After, frame: {{-17.103, 115.449}, {354.206, 177.103}}, bounds: {{0, 0}, {320, 160}}

Am I misunderstanding something or the author in the blog is wrong?

Divaricate answered 2/7, 2012 at 5:25 Comment(1)
Can you log both values before and after the transform, and log the scale value you are using as well? And actually include the output in your question :)Colorant
R
8

I think I've got it:

The blog is correct, according even to Apple themselves:

To translate or scale the coordinate system, you alter the view's bounds rectangle...

However bounds doesn't change because the rectangle itself is still the same size you've reported it, only the coordinate system has scaled with it. You see:

Changing the bounds rectangle sets up the basic coordinate system with which all drawing performed by the view begins.

and because we never explicitly change bounds, only the view's frame relative to its superview changes.

In fact, I can mathematically prove the bounds never change! Here, run this sample instead:

NSLog(@"scale: %f, velocity: %f", recognizer.scale, recognizer.velocity);
    NSLog(@"Before, frame: %@, bounds: %@", NSStringFromCGRect(recognizer.view.frame), NSStringFromCGRect(recognizer.view.bounds));
    recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
    NSLog(@"After, frame: %@, bounds: %@ transform:%@", NSStringFromCGRect(recognizer.view.frame), NSStringFromCGRect(recognizer.view.bounds), NSStringFromCGAffineTransform(recognizer.view.transform));

    recognizer.scale = 1;

Now, if you notice, the values reported from NSStringFromCGAffineTransform() multiplied by the bounds is equivalent to the view's frame. But what about what the blog said? Not necessarily accurate is right. Transformation matrices can apply to more than just the x and y of this thing, if we really wanted to, we could transform z values and rotate, and flip, and every which way, all of these change the frame property in non-linear ways, especially when used in tandom.

An interesting conundrum, if I do say so myself.

Rape answered 2/7, 2012 at 6:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.