IOS:屏幕旋转与Transform

IOS:屏幕旋转与Transform

 

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

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

  supportedInterfaceOrientations(6.0及以后)

  shouldAutorotateToInterfaceOrientation(6.0之前的系统)

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

 

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

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

SvRotateViewController
//
//  SvRotateViewController.m
//  SvRotateByTransform
//
//  Created by  maple on 4/21/13.
//  Copyright (c) 2013 maple. All rights reserved.
//

#import "SvRotateViewController.h"@interface SvRotateViewController ()@end@implementation SvRotateViewController- (void)viewDidLoad
{[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.
    self.view.backgroundColor = [UIColor grayColor];
}- (void)didReceiveMemoryWarning
{[super didReceiveMemoryWarning];// Dispose of any resources that can be recreated.
}- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{return YES;
}- (BOOL)shouldAutorotate
{return YES;
}- (NSUInteger)supportedInterfaceOrientations
{return UIInterfaceOrientationMaskAll;
}- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{NSLog(@"UIViewController will rotate to Orientation: %d", toInterfaceOrientation);
}- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{NSLog(@"did rotated to new Orientation, view Information %@", self.view);
}@end

  查看代码我们可以发现,我们的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,b为零的时候,x' = x + tx,y' = y + ty;即tx,ty分别代表x,y方向上的平移距离。

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

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

  

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

 

  实际应用中,我们将这些变化综合起来,即可完成所有二维的矩阵变化。现在我们在回过头来看看前面设备旋转时的输出,当设备位于Portrait的时候由于矩阵是标准矩阵,所以没有进行打印。当转到UIInterfaceOrientationLandscapeLeft方向的时候,我们的设备是顺时针转了90°(逆时针为正,顺时针为负),这个时候矩阵应该是(cos-90°,sin-90°,-sin-90°,cos-90°,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来完成旋转支持的,下一篇博客会介绍如何实现这种消息通知。

 

  注:转载请注明出处!欢迎大家加我QQ 1592232964,一起讨论共同进步。

转载于:https://www.cnblogs.com/smileEvday/archive/2013/04/23/Rotate1.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461148.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

input子系统详解4——输入事件驱动层源码分析

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、前言 由input子系统简介可知&#xff0c;input子系统分为三层&#xff1a; ​ 1、上层输入事件驱动层 涉及的文件有x210_kernel\drivers\input\evdev.c、mousedev.c 和 joydev.c文件&#xff0…

前端翻译:Activating Browser Modes with Doctype

一、前言                         原本备份&#xff1a; http://www.cnblogs.com/fsjohnhuang/p/3830623.html 由于本人英语能力有限&#xff0c;译本内容难免有误&#xff0c;望各位指正&#xff01; 本译文不含附录部分&#xff0c;请知悉。 二、译…

java公钥加密私钥解密过程_GPG加密解密过程

GPG加密解密过程一、Linux系统下1.安装yum安装[rootPOC-ORACLE ~]# yum install gnupg下载安装包安装https://www.gnupg.org/download/index.en.html查看gpg帮助[rootPOC-ORACLE ~]# gpg --helpgpg (GnuPG) 2.0.14libgcrypt 1.4.5Copyright (C) 2009 Free Software Foundation,…

魔兽世界客户端数据研究(三)

终于决定&#xff0c;还是通过wow model viewer起手&#xff0c;研究一下WOW的数据类型&#xff0c;从另一个角度&#xff0c;体验一把这个唯一让我充过值的游戏。 这将是一系列随笔&#xff0c;即在读代码的时候&#xff0c;顺便记录&#xff0c;以理清思路和加深映象。 其中…

input子系统详解5——参考驱动模板编写按键驱动

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、input类设备驱动的开发 &#xff08;1&#xff09;输入事件驱动层和框架核心层不需要动&#xff0c;只需要编写具体硬件驱动层代码。 &#xff08;2&#xff09;具体硬件驱动层的编程接口与调用…

java很多魔法数判断_可别在代码中写那么多魔法值了,脑壳疼!

1. 前言重构老代码中遇到了不少类似下面这种写法&#xff1a;public void attend(String value) {if ("0".equals(value)) {//todo} else if ("1".equals(value)) {//todo} else {//todo}}脑壳疼&#xff01;从 Java 语法上无懈可击&#xff0c;但是从业务…

十分钟让你明白Objective-C的语法(和Java、C++的对比)

2019独角兽企业重金招聘Python工程师标准>>> 很多想开发iOS&#xff0c;或者正在开发iOS的程序员以前都做过Java或者C&#xff0c;当第一次看到Objective-C的代码时都会头疼&#xff0c;Objective-C的代码在语法上和Java, C有着很大的区别&#xff0c;有的同学会感觉…

稀疏多项式的运算

问题描述&#xff1a; 已知稀疏多项式Pn(X)c1x^e1c2x^e2....cmx^em,其中nem>em-1>....>e1>0; ci!0,m>1.试采用存储量同多项式项数m成正比的顺序存储结构&#xff0c;编写求Pn(x0)的算法&#xff08;x0为给定值&#xff09;&#xff0c;并分析你的算法的时间复杂…

I2C子系统详解1——I2C总线设备的驱动框架

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考博客 I2C总线驱动框架详解 linux内核I2C子系统详解 一、I2C总线的物理特征 这部分内容的简介可见博客&#xff1a;SPI、I2C、UART&#xff08;即串口&#xff09;三种串行总线详解。 &#x…

sqlite4java下载_使用sqlite4java的UnsatisfiedLinkError,没有sqlite4java-osx-amd64

我对这个问题有类似的问题&#xff1a;我正在运行一个使用sqlite的脚本,虽然我能够通过命令行成功运行sqlite3,但是当我尝试运行脚本时,我总是遇到这个错误&#xff1a;SEVERE: [sqlite] sqliteQueue[master.catalog]: error running job queuecom.almworks.sqlite4java.sqlite…

神经网络编程入门

本文主要内容包括&#xff1a; (1) 介绍神经网络基本原理&#xff0c; (2) AForge.NET实现前向神经网络的方法&#xff0c; (3) Matlab实现前向神经网络的方法 。 第0节、引例 本文以Fisher的Iris数据集作为神经网络程序的测试数据集。Iris数据集可以在http://en.wikipedia.or…

I2C子系统详解2——I2C核心层源码分析

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、前言 由I2C总线设备的驱动框架可知&#xff0c;I2C总线设备驱动框架涉及的文件如下&#xff1a; &#xff08;1&#xff09;I2C设备驱动层相关的文件 x210开发板的电容触摸屏gslX680采用I2C接口…

软考复习之路—组成原理

计算机系统的基础知识应该是作为一个编程人员必备的一门课程&#xff0c;仅仅有了解了计算机的组成&#xff0c;程序在计算 机中的存储状态&#xff0c;运算等基本内容&#xff0c;我们才干继续对计算机有更深层次的认识&#xff0c;更easy学习与上手。比方说要 想学习操作系统…

python内存管理机制错误_Python内存管理机制和垃圾回收机制的简单理解

一、内存管理机制1.由c开发出来的cpython2.include / objests3.需要下载python源码包4.Pyobject&#xff1a;floatPyVarObject&#xff1a;5.在python中所有东西创建对象的时候&#xff0c;内部都会存储一个数据// 维护双向链表struct _object *_ob_next;struct _object *_ob_p…

C#中几种数据库的大数据批量插入

C#语言中对SqlServer、Oracle、SQLite和MySql中的数据批量插入是支持的&#xff0c;不过Oracle需要使用Orace.DataAccess驱动。 IProvider里有一个用于实现批量插入的插件服务接口IBatcherProvider。批量插入的实现可以通过实现该接口来实现。 /// <summary>/// 提供数据…

求背包问题所有解(C++实现)

这是我学习数据结构时的一道上机作业&#xff0c;那时还没养成写注释的习惯&#xff0c;所以各位得受点苦了。 只是简易背包问题。 代码&#xff1a; 展开 1 // 背包问题所有解2 // 作者:王锦 3 // 邮箱:jinkswvip.qq.com4 5 #include "stdafx.h"6 #include <iost…

I2C子系统详解3——I2C总线驱动层代码分析

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 一、前言 由I2C总线设备的驱动框架可知&#xff0c;I2C总线设备的驱动框架涉及的文件如下&#xff1a; &#xff08;1&#xff09;I2C设备驱动层相关的文件 x210开发板的电容触摸屏gslX680采用I2C接…

java join 异常_Java:守护进程:thread.join()没有完成,当在一个线程中抛出异常时...

我写了一个Java守护进程(一个实现守护进程和Runnable的类)&#xff0c;现在我遇到了以下问题&#xff1a;在init()中&#xff0c;我创建了一个新线程 . Thread thread new Thread(this); 在start()中我启动新线程 . thread.start() . 在运行中我做了很多不同的事情......然后发…

硬链接与符号链接的比较?

今天就说说硬链接&#xff08;实体链接&#xff09;与符号链接&#xff08;类似Windows的快捷方式&#xff09;的不同?首先我们应知道&#xff1a;每个档案都会占用一个inode ,档案内容由 inode记录来指向;想要读取该档案&#xff0c;必须要经过目录记录的文件名来指向正确的i…

JAVA--自制斐波那契数列输出

累了&#xff0c;写点简单的。 1 public class hello {2 3 /**4 * param args5 */6 public static void main(String[] args) {7 int Fabnum 10;8 int sum 0;9 System.out.print("Serial:\t"); 10 for(int i 1…