IOS4 note 15 (6) Transform

Transform

 

A view’s transform property alters how the view is drawn — it may, for example, change the view’s perceived size and orientation — without affecting its bounds and center. A transformed view continues to behave correctly: a rotated button, for example, is still a button, and can be tapped in its apparent location and orientation.

 

A transform value is a CGAffineTransform, which is a struct representing six of the nine values of a 3×3 transformation matrix (the other three values are constants, so there’s no point representing them in the struct). You may have forgotten your highschool linear algebra, so you may not recall what a transformation matrix is. For the details, which are quite simple really, see the “Transforms” chapter of Apple’s Quartz 2D Programming Guide, especially the section called “The Math Behind the Matrices.”

But you don’t really need to know those details, because convenience functions, whose names start with “CGAffineTransformMake,” are provided  for creating  three of  the basic types of transform: rotation, scaling, and translation (i.e., changing the view’s apparent position). A fourth basic transform type, skewing or shearing, has no convenience function.

 

By default, a view’s transformation matrix is CGAffineTransformIdentity, the identity transform. It has no visible effect, so you’re unaware of it. Any transform that you do apply takes place around the view’s center, which is held constant.

Here’s some code to illustrate use of a transform:

UIView* v1 = [[UIView alloc] initWithFrame:CGRectMake(113, 111, 132, 194)];

v1.backgroundColor = [UIColor colorWithRed:1 green:.4 blue:1 alpha:1];

UIView* v2 = [[UIView alloc] initWithFrame:CGRectInset(v1.bounds, 10, 10)];

v2.backgroundColor = [UIColor colorWithRed:.5 green:1 blue:0 alpha:1];

[self.window addSubview: v1];

[v1 addSubview: v2];

v1.transform = CGAffineTransformMakeRotation(45 * M_PI/180.0);

[v1 release]; [v2 release];

 

The transform property of the view v1 is set to a rotation transform. The result is that the view appears to be rocked 45 degrees clockwise. (I think in degrees, but Core Graphics thinks in radians, so my code has to convert.) Observe that the view’s center property is unaffected, so that the rotation seems to have occurred around the view’s center. Moreover, the view’s bounds property is unaffected; the internal coordinate system  is unchanged, so  the subview  is drawn  in  the same place  relative to  its superview. The view’s frame, however, is now meaningless, as no mere rectangle can describe the region of the superview apparently occupied by the view. The rule is that if a view’s transform is not the identity transform, you should neither get nor set its frame. Also, automatic resizing of a subview requires that the superview’s transform be the identity transform.

 

Suppose,  instead of CGAffineTransformMakeRotation, we call CGAffineTransformMakeScale, like this:

 

v1.transform = CGAffineTransformMakeScale(1.8, 1);

 

The bounds property of the view v1 is still unaffected, so the subview is still drawn in the same place relative to its superview; this means that the two views seem to have stretched horizontally together. No bounds or centers were harmed by the application of this transform!

 

Transformation matrices can be chained. There are convenience functions for applying one transform to another. Their names do not contain “Make.” These functions are not commutative; that is, order matters. If you start with a transform that translates a view to the right and then apply a rotation of 45 degrees, the rotated view appears to the right of its original position; on the other hand, if you start with a transform that rotates a view 45 degrees and  then apply a translation to the right, the meaning of “right” has changed, so the rotated view appears 45 degrees down from its original position. 

 

UIView* v1 = [[UIView alloc] initWithFrame:CGRectMake(20, 111, 132, 194)];

v1.backgroundColor = [UIColor colorWithRed:1 green:.4 blue:1 alpha:1];

UIView* v2 = [[UIView alloc] initWithFrame:v1.bounds];

v2.backgroundColor = [UIColor colorWithRed:.5 green:1 blue:0 alpha:1];

Then I’ll apply two successive transforms to the subview, leaving the superview to show where  the subview was originally. In this example, I translate and then rotate:

v2.transform = CGAffineTransformMakeTranslation(100, 0);

v2.transform = CGAffineTransformRotate(v2.transform, 45 * M_PI/180.0);

In this example, I rotate and then translate (Figure 14-11):

v2.transform = CGAffineTransformMakeRotation(45 * M_PI/180.0);

v2.transform = CGAffineTransformTranslate(v2.transform, 100, 0);

 

The function CGAffineTransformConcat concatenates two transform matrices using matrix multiplication. Again, this operation is not commutative. The order is the opposite of the order when using convenience functions for applying one transform to another.

For example:

CGAffineTransform r = CGAffineTransformMakeRotation(45 * M_PI/180.0);

CGAffineTransform t = CGAffineTransformMakeTranslation(100, 0);

v2.transform = CGAffineTransformConcat(t,r); // not r,t

 

To remove a transform from a combination of transforms, apply its inverse. A convenience  function  lets  you obtain  the  inverse of  a given  affine  transform. Again, order matters. In this example, I rotate the subview and shift it to its “right,” and then remove the rotation:

CGAffineTransform r = CGAffineTransformMakeRotation(45 * M_PI/180.0);

CGAffineTransform t = CGAffineTransformMakeTranslation(100, 0);

v2.transform = CGAffineTransformConcat(t,r);

v2.transform = CGAffineTransformConcat(CGAffineTransformInvert(r), v2.transform);

 

Finally, as there are no convenience methods for creating a skew (shear) transform, I’ll illustrate by creating one manually, without further explanation:

v1.transform = CGAffineTransformMake(1, 0, -0.2, 1, 0, 0);

 

Transforms are useful particularly as  temporary visual  indicators. For example, you might call attention to a view by applying a transform that scales it up slightly, and then applying the  identity transform to restore  it to  its original size, and animating those changes.

 

你可能感兴趣的:(IOS4 note 15 (6) Transform)