UIView的transform属性是一个CGAffineTransform类型,用于在二维空间做旋转,缩放和平移。CGAffineTransform是一个可以和二维空间向量(例如CGPoint)做乘法的3X2的矩阵,图显示了3X2的矩阵:
用矩阵表示CGAffine和CGPoint
等价于:
x' = ax+cy+tx;
y' = bx+dy+ty;
什么是仿射?仿射的意思是无论变换矩阵用什么值,图层中平行的两条线在变换之后仍然保持平行,CGAffineTransform可以做出任意符合上述标注的变换,图显示了一些仿射和非仿射的变换:
仿射和非仿射
CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat y)实例:
@interface ViewController (){
CALayer *blueLayer;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
blueLayer = [CALayer layer];
blueLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
blueLayer.backgroundColor = [UIColor blueColor].CGColor;
[self.view.layer addSublayer:blueLayer];
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(75.0f, 175.0f, 25, 25)];
btn.backgroundColor = [UIColor yellowColor];
[self.view addSubview:btn];
[btn addTarget:self action:@selector(click:) forControlEvents:UIControlEventTouchUpInside];
}
- (void)click:(id)sender{
NSLog(@"befer frame x=%f, y=%f, width=%f, height=%f, bound x=%f, y=%f, width=%f, height=%f , position x=%f, y=%f, anchorPoint x=%f, y=%f", blueLayer.frame.origin.x, blueLayer.frame.origin.y, blueLayer.frame.size.width, blueLayer.frame.size.height, blueLayer.bounds.origin.x, blueLayer.bounds.origin.y, blueLayer.bounds.size.width, blueLayer.bounds.size.height, blueLayer.position.x, blueLayer.position.y, blueLayer.anchorPoint.x, blueLayer.anchorPoint.y);
blueLayer.affineTransform = CGAffineTransformMake(1, 0.9, 0, 1, 0, 0);
NSLog(@"befer frame x=%f, y=%f, width=%f, height=%f, bound x=%f, y=%f, width=%f, height=%f , position x=%f, y=%f, anchorPoint x=%f, y=%f", blueLayer.frame.origin.x, blueLayer.frame.origin.y, blueLayer.frame.size.width, blueLayer.frame.size.height, blueLayer.bounds.origin.x, blueLayer.bounds.origin.y, blueLayer.bounds.size.width, blueLayer.bounds.size.height, blueLayer.position.x, blueLayer.position.y, blueLayer.anchorPoint.x, blueLayer.anchorPoint.y);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
结合实例,明白x会跟着a值进行比例缩放,y会跟着d的值进行比例缩放,x会跟着c的值进行斜切变换,y会跟着b的值进行斜切变换,x会跟着tx平移, y会跟着ty平移,改变的的过程中View的point(中心点)是不会改变的。
函数:
CGAffineTransformMakeTranslation(CGFloat tx,CGFloat ty);//根据本身的transform进行平移
CGAffineTransformTranslate(CGAffineTransform t,CGFloat tx,CGFloat ty);//根据本身的transform后者另外的transform进行平移
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle); //旋转
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy); //缩放
CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2); //混合两个已存的矩阵
当操纵一个变换的时候,初始生成一个什么都不做的变换很重要--也就是创建一个CGAffineTransform
类型的空值,矩阵论中称作单位矩阵,Core Graphics同样也提供了一个方便的常量:
CGAffineTransfromIdentity
实现一个斜切变换:
@implementation ViewController
CGAffineTransform CGAffineTransformMakeShear(CGFloat x, CGFloat y)
{
CGAffineTransform transform = CGAffineTransformIdentity;
transform.c = -x;
transform.b = y;
return transform;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//shear the layer at a 45-degree angle
self.layerView.layer.affineTransform = CGAffineTransformMakeShear(1, 0);
}
@end
3D变换
和CGAffineTransform
类似,CATransform3D
也是一个矩阵,但是和2x3的矩阵不同,CATransform3D
是一个可以在3维空间内做变换的4x4的矩阵, 下国显示了4x4的矩阵:
4x4的矩阵
X,Y,Z轴,以及围绕它们旋转的方向
CATransform3D结构
struct CATransform3D
{
CGFloat m11(x缩放), m12(y切变), m13(旋转), m14();
CGFloat m21(x切变), m22(y缩放), m23(), m24();
CGFloat m31(旋转), m32(), m33(), m34(透视效果,要操作的这个对象要有旋转的角度,否则没有效果。正直/负值都有意义);
CGFloat m41(x平移), m42(y平移), m43(z平移), m44();
};
函数:
CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z); //旋转
CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz); //缩放
CATransform3DMakeTranslation(CGFloat tx, CGFloat ty, CGFloat tz); //平移