CGAffineTransform(UIView仿射变换)
来源:互联网 发布:财务报销软件集思图友 编辑:程序博客网 时间:2024/05/16 04:49
一、CGAffineTransform介绍
CGAffineTransform可以使控件的产生移动、缩放、旋转效果,其坐标系统采用的是二维坐标系,坐标原点为屏幕的左上角,向右为x轴正方向,向下为y轴正方向。
二、方法介绍
下面以使用一个UIImageView图片为例,结合UIView动画、手势进行演示
@property(strong,nonatomic)UIImageView *imageView;- (void)viewDidLoad{ [super viewDidLoad]; [self.view addSubview:self.imageView];}-(UIImageView *)imageView{ if (_imageView==nil) { _imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"aa"]]; _imageView.frame = CGRectMake(0, 0, 100, 80); } return _imageView;}
- 移动控件
1、CGAffineTransformMakeTranslation实现以初始位置为基准,在x轴方向上平移x单位,在y轴方向上平移y单位
// 格式CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)// 使用 将图片左(100px)下(150px)方向移动CGAffineTransform transform = CGAffineTransformMakeTranslation(-100, 150);self.imageView.transform = transform;
2、CGAffineTransformTranslate在已有的transform基础上,增加 移动 效果
// 格式 CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)// 使用self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, -50, 150);
- 缩放控件
1、CGAffineTransformMakeScale实现以初始位置为基准,在x轴方向上缩放x倍,在y轴方向上缩放y倍
// 格式 tx,ty表示的是倍数CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)// 使用 将图片放大2倍self.imageView.transform = CGAffineTransformMakeScale(2, 2);
2、CGAffineTransformScale在已有的transform基础上,增加 缩放 效果
// 格式 CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)// 使用 宽度缩小一倍,高度拉伸1.5倍self.imageView.transform = CGAffineTransformScale(self.imageView.transform, 0.5 1.5);
- 旋转控件
1、CGAffineTransformMakeRotation实现以初始位置为基准,将坐标系统旋转angle弧度(弧度=π/180×角度,M_PI弧度代表180角度)
// 格式 angle为弧度CGAffineTransformMakeRotation(CGFloat angle)// 使用 self.imageView.transform = CGAffineTransformMakeRotation(M_PI);
2、CGAffineTransformRotate在已有的transform基础上,增加 旋转 效果
// 格式 CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)// 使用 self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, M_PI/2.0);
- 最初transform
控件的transform属性默认值为CGAffineTransformIdentity,可以在形变之后设置该值以还原到最初状态
// 使用self.imageView.transform = CGAffineTransformIdentity;
- 反转变换效果
CGAffineTransformInvert可以实现于transform相反的效果,比如放大3倍效果则缩小为1/3,向x轴正方向平移100px效果则为向负方向平移100px
CGAffineTransform transform = CGAffineTransformMakeScale(3, 3); //相反 缩小至1/3 transform = CGAffineTransformInvert(transform);self.imageView.transform = transform;
- 结合变换效果
CGAffineTransformConcat结合两种变换
//定义两种ransformCGAffineTransform transform_A = CGAffineTransformMakeTranslation(0, 200);CGAffineTransform transform_B = CGAffineTransformMakeScale(0.2, 0.2);transform = CGAffineTransformConcat(transform_B, transform_A);
- 判断变换
1、CGAffineTransformIsIdentity可以判断view.transform当前状态是否是最初状态
bool CGAffineTransformIsIdentity(CGAffineTransform t)
2、CGAffineTransformEqualToTransform可以判断两种transform是否是一样的
bool CGAffineTransformEqualToTransform(CGAffineTransform t1, CGAffineTransform t2)
- 使用仿射变换转换point,size,rect
1、CGPointApplyAffineTransform转换point,使用一种transform来得到转换后的point
// transform 可以是移动、放大、旋转CGPoint CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t)// 使用CGPoint point = CGPointMake(123, 222);CGPoint pointNew = CGPointApplyAffineTransform(point, CGAffineTransformMakeTranslation(77, 28));
2、CGSizeApplyAffineTransform转换size,使用一种transform来得到转换后的size
//CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t)// 使用CGSize size = CGSizeMake(33, 44);CGSize sizeNew = CGSizeApplyAffineTransform(size, CGAffineTransformMakeScale(2, 2));
3、CGRectApplyAffineTransform转换rect,使用一种transform来得到转换后的rect
//CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t)// 使用CGRect rect = CGRectMake(20, 30, 50, 100);CGRect rectNew = CGRectApplyAffineTransform(rect, CGAffineTransformMakeRotation(M_PI));
三、CGAffineTransform原理
CGAffineTransform形变是通过”仿射变换矩阵”来控制的,其中平移是矩阵相加,旋转与缩放则是矩阵相乘,CGAffineTransform形变就是把二维形变使用一个三维矩阵来表示,系统提供了CGAffineTransformMake结构体来控制形变。
CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty)
该三维变换矩阵如下:
变换矩阵
通过变换矩阵左乘向量,将空间中的一个点集从一个坐标系变换到另一个坐标系中,计算方式如下
矩阵相乘
计算结果
由此可知,
tx:用来控制在x轴方向上的平移
ty:用来控制在y轴方向上的平移
a:用来控制在x轴方向上的缩放
d:用来控制在y轴方向上的缩放
abcd:共同控制旋转
所以以下写法都是等同的
- 移动:[ 1 0 0 1 tx ty ]
CGAffineTransformMakeTranslation(100, 100);CGAffineTransformMake(1, 0, 0, 1, 100, 100);
- 缩放:[ sx 0 0 sy 0 0 ]
CGAffineTransformMakeScale(2, 0.5);CGAffineTransformMake(2, 0, 0, 0.5, 0, 0);
- 旋转:[ cos(angle) sin(angle) -sin(angle) cos(angle) 0 0 ]
CGAffineTransformMakeRotation(M_PI*0.5);CGAffineTransformMake(cos(M_PI * 0.5), sin(M_PI * 0.5), -sin(M_PI * 0.5), cos(M_PI * 0.5), 0, 0);
- 最初:[ 1 0 0 1 0 0 ]
CGAffineTransformIdentity;CGAffineTransformMake(1, 0, 0, 1, 0, 0);
四、应用
- 结合UIView动画使用
[UIView animateWithDuration:1.0 animations:^{ //缩放 CGAffineTransform transform = CGAffineTransformMakeScale(2, 2); ws.imageView.transform = transform;} completion:^(BOOL finished) { [UIView animateWithDuration:1.0 animations:^{ //回到最初 ws.imageView.transform = CGAffineTransformIdentity; } completion:nil]; }];
- 结合手势使用
//点击手势UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];tap.numberOfTapsRequired = 2;[self.testView addGestureRecognizer:tap];//拖拽手势UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)];[self.testView addGestureRecognizer:pan];#pragma mark - 点击手势-(void)tapAction:(UITapGestureRecognizer *)tap{ if (CGAffineTransformIsIdentity(self.testView.transform)) { [UIView animateWithDuration:0.5 animations:^{ self.testView.transform = CGAffineTransformScale(self.testView.transform, 1.3, 2); }]; } else{ [UIView animateWithDuration:0.5 animations:^{ self.testView.transform = CGAffineTransformIdentity; }]; }}#pragma mark - 拖拽手势-(void)panAction:(UIPanGestureRecognizer *)pan{ //获取手势位置 CGPoint position = [pan translationInView:self.testView]; //通过 CGAffineTransformTranslate 获取 新的transform self.testView.transform = CGAffineTransformTranslate(self.testView.transform, position.x, position.y); //将增加置为 0 [pan setTranslation:CGPointZero inView:self.testView];}
五、Demo地址
1、UIView动画
2、手势
3、加载
六、参考地址
1、iOS形变之CGAffineTransform
2、iOS学习必须了解的七大手势
- CGAffineTransform(UIView仿射变换)
- 仿射变换CGAffineTransform
- CGAffineTransform 仿射变换
- CGAffineTransform 进行仿射变换
- oc UI 仿射变换CGAffineTransform
- CoreGraphics 之CGAffineTransform仿射变换
- CoreGraphics 之CGAffineTransform仿射变换(3)
- IOS开发UI篇--仿射变换(CGAffineTransform)使用小结
- iOS利用仿射变换(CGAffineTransform)制作动画效果
- IOS开发UI篇--仿射变换(CGAffineTransform)使用小结
- ios UItableView,UITableViewHeaderFooterView分组头部的重用机制,简单地仿射变换CGAffineTransform
- iOS下的2D仿射变换机制(CGAffineTransform相关)
- iOS下的2D仿射变换机制CGAffineTransform相关
- CGAffineTransform 仿射转换
- UI一揽子计划 23 (动画的使用场景、UIView动画、CGAffineTransform2D仿射变换、CALayer、CAAnimation、)
- 仿射变换&透视变换
- 几何变换 -- 仿射变换
- CGAffineTransform 放射变换
- MySQL EXPLAIN详解
- 小波变换通俗解释
- 区别: 计算机视觉&图像处理&计算机图形学
- js小知识
- 是启动线程和调用线程的run方法
- CGAffineTransform(UIView仿射变换)
- struts2 springmvc 多个对象时 如何准确绑定?
- [转载]四轴飞行器1.4 姿态解算和Matlab实时姿态显示
- SQL SERVER 2008 R2序列号
- Python 为什么list不能作为字典的key?
- 反编译后代码混淆问题小分析
- 图像算法---白平衡AWB(讲的很好)
- Intellij IDEA 发布后的项目在哪里
- 单点登录