【转】IOS屏幕旋转与View的transform属性之间的关系,比较底层

简介:

iTouch,iPhone,iPad设置都是支持旋转的,如果我们的程序能够根据不同的方向做出不同的布局,体验会更好。

  如何设置程序支持旋转呢,通常我们会在程序的info.plist中进行设置Supported interface orientations,添加我们程序要支持的方向,而且程序里面每个viewController也有方法

  supportedInterfaceOrientations(6.0及以后)

  shouldAutorotateToInterfaceOrientation(6.0之前的系统)

  通过viewController的这些方法,我们可以做到更小粒度的旋转控制,如程序中仅仅允许个别界面旋转。

 

一、屏幕旋转背后到底做了什么呢?

  下面我们看个简单的例子,用xcode新建一个默认的单视图工程,然后在对应viewController的响应旋转后的函数中输出一下当前view的信息,代码如下:

  View Code

查看代码我们可以发现,我们的viewController支持四个方向,然后在旋转完成的didRotateFromInterfaceOrientation函数中打印了self.view的信息,旋转一圈我们可以看到如下输出:

  设备的初始方向是UIInterfaceOrientationPortrait的,然后顺时针依次经过LandscapeLeftPortraitUpsideDownLandscapeRight,最后再回到UIInterfaceOrientationPortrait方向。仔细看的话我们会发现在旋转的过程中,除了frame之外,Transform也在一直变化。观察frame发现,它的变化应该是由于系统的状态栏引起的。于是将系统状态栏隐藏掉,在输出发现frame果然不再变化。因此我们可以怀疑屏幕旋转是通过变化Transform实现的。

 

二、什么是Transform

  Transform(变化矩阵)是一种3×3的矩阵,如下图所示:

  通过这个矩阵我们可以对一个坐标系统进行缩放,平移,旋转以及这两者的任意组着操作。而且矩阵的操作不具备交换律,即矩阵的操作的顺序不同会导致不同的结果。UIView有个transform的属性,通过设置该属性,我们可以实现调整该view在其superView中的大小和位置。

  矩阵实现坐标变化背后的数学知识:

  设x,y分别代表在原坐标系统中的位置,x',y'代表通过矩阵变化以后在新的系统中的位置。其中式1就是矩阵变化的公式,对式1进行展开以后就可以得到式2。从式2我们可以清楚的看到(x,y)到(x',y')的变化关系。

  1)当c,b,tx,ty都为零时,x' = ax,y' = by;即a,d就分别代表代表x,y方向上放大的比例;当a,d都为1时,x' = x,y' = y;这个时候这个矩阵也就是传说中的CGAffineTransformIdentity(标准矩阵)。

  2)当a,d为1,c,d为零的时候,x' = x + tx,y' = y + ty;即tx,ty分别代表x,y方向上的平移距离。

  3)前面两种情况就可以实现缩放和平移了,那么旋转如何表示呢?

  假设不做平移和缩放操作,那么从原坐标系中的一点(x,y)旋转α°以后到了新的坐标系中的一点(x',y'),那么旋转矩阵如下:

  

  展开以后就是x' = xcosα - ysinα,y' = xsinα + ycosα;

 

  实际应用中,我们将这些变化综合起来,即可完成所有二维的矩阵变化。现在我们在回过头来看看前面设备旋转时的输出,当设备位于Portrait的时候由于矩阵是标准矩阵,所以没有进行打印。当转到UIInterfaceOrientationLandscapeLeft方向的时候,我们的设备是顺时针转了90°,这个时候矩阵应该是(cos90°,sin90°,-sin90°,cos90°,tx,ty),由于未进行平移操作所以tx,ty都为0,刚好可以跟我们控制台输出:"<UIView: 0x8075390; frame = (0 0; 320 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x8074980>>"一致。观察其他两个方向的输出,发现结果均和分析一致。

  由此可以发现屏幕旋转其实就是通过view的矩阵变化实现,当设备监测到旋转的时候,会通知当前程序,当前程序再通知程序中的windowwindow会通知它的rootViewController的,rootViewController对其viewtransform进行设置,最终完成旋转。

  如果我们直接将一个view添加到window上,系统将不会帮助我们完成旋操作,这个时候我们就需要自己设置该viewtransform来实现旋转了。这种情况虽然比较少,但是也存在的,例如现在很多App做的利用状态栏进行消息提示的功能就是利用自己创建window并且自己设置transform来完成旋转支持的。

本文转自编程小翁博客园博客,原文链接:http://www.cnblogs.com/wengzilin/p/3258455.html,如需转载请自行联系原作者

相关文章
|
iOS开发
iOS CAEmitterLayer 属性介绍
iOS CAEmitterLayer 属性介绍
55 0
|
4月前
|
iOS开发 UED 开发者
iOS 手势中cancelsTouchesInView delaysTouchesBegan delaysTouchesEnded 三种属性的使用
iOS 手势中cancelsTouchesInView delaysTouchesBegan delaysTouchesEnded 三种属性的使用
163 9
|
5月前
|
Swift iOS开发
iOS开发-属性的内存管理
【8月更文挑战第12天】在iOS开发中,属性的内存管理至关重要,直接影响应用性能与稳定性。主要策略包括:`strong`(强引用),不维持对象生命期,可用于解除循环引用;`assign`(赋值),适用于基本数据类型及非指针对象属性;`copy`,复制对象而非引用,确保对象不变性。iOS采用引用计数管理内存,ARC(自动引用计数)自动处理引用增减,简化开发。为避免循环引用,可利用弱引用或Swift中的`[weak self]`。最佳实践包括:选择恰当的内存管理策略、减少不必要的强引用、及时释放不再使用的对象、注意block内存管理,并使用Xcode工具进行内存分析。
|
5月前
|
BI Linux 数据安全/隐私保护
忘了 iOS(iPad、IPhone) 设备上的「屏幕使用时间」密码怎么办?找回屏幕密码
忘了 iOS(iPad、IPhone) 设备上的「屏幕使用时间」密码怎么办?找回屏幕密码
156 0
|
7月前
|
前端开发 iOS开发
input框设置placeholder属性在iOS中显示不完整
input框设置placeholder属性在iOS中显示不完整
87 1
|
8月前
|
iOS开发
iOS16.1系统由于一个系统弹窗无法取消,导致屏幕卡死无法关机问题及解决方案
iOS16.1系统由于一个系统弹窗无法取消,导致屏幕卡死无法关机问题及解决方案
874 0
|
iOS开发
iOS 渐变颜色 CGGradientCreateWithColorComponents 属性介绍
iOS 渐变颜色 CGGradientCreateWithColorComponents 属性介绍
172 0
|
iOS开发
iOS UIDevice & 屏幕旋转检测
iOS UIDevice & 屏幕旋转检测
57 0
|
存储 安全
11-iOS关联对象实现weak属性
11-iOS关联对象实现weak属性
323 0
|
安全 vr&ar 数据安全/隐私保护
iOS移动设备屏幕镜像电脑软件AirServer2023
AIrServer是一款ios投屏到mac的专用软件,可将iOS上的音频,视频,照片,幻灯片和镜像接收通过AIrPlay投射到Mac。AIrserver 7 mac版可以实现将手机上的媒体文件以及其他操作投射到电脑上进行操作。使用AIrServer,您现在可以从Mac,iOS,PC,
217 0