首页 > 代码库 > IOS 以随意点为圆心 旋转UIView

IOS 以随意点为圆心 旋转UIView

环绕底边中点旋转

      技术分享                   技术分享



 UIView本身是支持旋转的,能够用UIView.transform属性实现旋转。

The origin of the transform is the value of the center property, or the layer’s anchorPoint property if it was changed.

这个旋转默认是环绕这UIView.center或者UIView.layer.anchorPoint旋转的。

似乎UIView.layer.anchorPoint属性给了我们一个能实现环绕随意点旋转的可能,其实也确实可以通过UIView.layer.anchorPoint实现环绕随意点旋转。

囿于UIView.layer.anchorPoint属性的复杂性、关联性太强(參考http://www.cnblogs.com/benbenzhu/p/3615516.html),我尝试从其它方向入手。

幸运的是,这问题在数学上早已解决(不应这么说,因果弄反了,数学上解决后。计算机才应用),就是用仿射矩阵变换。

环绕随意点旋转的仿射矩阵例如以下(摘自百度百科)

目标图形以(x, y)为轴心逆时针旋转theta弧度,变换矩阵为:
[ cos(theta)   -sin(theta)     x-x*cos+y*sin]
[ sin(theta)   cos(theta)      y-x*sin-y*cos ]
[ 0             0                  1        ]
相当于两次平移变换与一次原点旋转变换的复合:
[1 0 x] [cos(theta) -sin(theta) 0]  [1 0- x]
[0 1 y] [sin(theta) cos(theta)  0]  [0 1 -y]
[0 0 1] [ 0          0          1]  [0 0 1]
这里是以空间任一点为圆心旋转的情况。

能够直接使用上面第一个公式计算放射矩阵。

我依据上面第二个等效公式和ios的API。归纳出以下函数,用于计算仿射矩阵。实现环绕UIView的坐标系的随意点旋转。

CGAffineTransform  GetCGAffineTransformRotateAroundPoint(float centerX, float centerY ,float x ,float y ,float angle)
{
    x = x - centerX; //计算(x,y)从(0,0)为原点的坐标系变换到(CenterX ,CenterY)为原点的坐标系下的坐标
    y = y - centerY; //(0,0)坐标系的右横轴、下竖轴是正轴,(CenterX,CenterY)坐标系的正轴也一样

    CGAffineTransform  trans = CGAffineTransformMakeTranslation(x, y);
    trans = CGAffineTransformRotate(trans,angle);
    trans = CGAffineTransformTranslate(trans,-x, -y);
    return trans;
}
当中(centerX。centerY)是UIView.center属性值.须要注意的是每次设置UIView.transform时。最好先设置为CGAffineTransformIdentity以恢复UIView为初始视图,否则会有意想不到的效果


示意代码

UIView *view = ......

float centerX = view.bounds.size.width/2;
float centerY = view.bounds.size.height/2;
float x = view.bounds.size.width/2;
float y = view.bounds.size.height;

CGAffineTransform trans = GetCGAffineTransformRotateAroundPoint(centerX,centerY ,x ,y ,45.0/180.0*M_PI);
view.transform = CGAffineTransformIdentity;
view.transform = trans;




IOS 以随意点为圆心 旋转UIView