UIView及其子类围绕任意点旋转的方法
2015-06-26 11:55
761 查看
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),我尝试从其他方向入手。
幸运的是,这问题在数学上早已解决(不应这么说,因果弄反了,数学上解决后,计算机才应用),就是用仿射矩阵变换。
围绕任意点旋转的仿射矩阵如下(摘自百度百科) :
可以直接使用上面第一个公式计算放射矩阵;
我根据上面第二个等效公式和ios的API,归纳出下面函数,用于计算仿射矩阵,实现围绕UIView的坐标系的任意点旋转。
其中(centerX,centerY)是UIView.center属性值 .
需要注意的是每次设置UIView.transform时,最好先设置为CGAffineTransformIdentity以恢复UIView为初始视图,否则会有意想不到的效果
示意代码
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;
相关文章推荐
- UIKit:UITextField属性解析
- 【Android UI设计与开发】第13期:顶部标题栏(四)自定义ActionBar风格和样式
- Build生成者模型
- 【Android UI设计与开发】第12期:顶部标题栏(三)ActionBar实现层级导航的返回效果
- ios学习笔记:tableviewcell中ui设置frame问题
- SPOJ - DQUERY 【主席树】
- S5PV210开发系列四_uCGUI的移植
- [XCode] XCode 中设置 UI 部件的 z-order
- Windows 10 build 10149手机版上手多图欣赏
- [Android基础知识] 之二十二 UI设计之 LayoutInflater详解
- 问题解决——开启Guest后仍无法共享打印机
- LintCode Unique Characters 判断字符串是否没有重复字符
- Egret之egret.gui.List的使用教程
- android 开源项目GuillotineMenu,酷炫的铡刀菜单
- UI设计: iOS 启动页的原则
- UI界面并不是只有白色设计才叫极简设计
- Leetcode|Repeated DNA Sequences
- iOS开发中UILocalNotification实现本地通知实现提醒功能
- uitableview 两种设置重用cell的方式
- select, iocp, epoll,kqueue及各种I/O复用机制