首页 > 代码库 > 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 ,45.0/180.0*M_PI);
view.transform = CGAffineTransformIdentity;
view.transform = trans;




IOS 以任意点为圆心 旋转UIView