6.3  View之间的切换

在上面的练习中我们通过移动组件的位置和调整组件的大小来处理横向与纵向的界面布局。但是在界面中有很多组件的时候,对每个组件都进行这样的操作确实是一个麻烦的事情。下面我们看看处理屏幕旋转的第二种方法,在ViewController开始旋转之前进行view的切换。

实战:屏幕旋转时进行view的切换

打开Xcode,创建一个新的Xcode项目,选择View-based 应用程序模板,项目名称为AutoRotationSwap。

修改AutoRotationSwapViewController.h文件。

  1. #import <UIKit/UIKit.h>
  2. #define degreesToRadians(x) (M_PI * (x) / 180.0)
  3. @interface AutoRotationSwapViewController : UIViewController {
  4. UIView *landscape;
  5. UIView *portrait;
  6. UIButton *landscapeOneButton;
  7. UIButton *portraitOneButton;
  8. UIButton *landscapeTwoButton;
  9. UIButton *portraitTwoButton;
  10. }
  11. @property (nonatomic, retain) IBOutlet UIView *landscape;
  12. @property (nonatomic, retain) IBOutlet UIView *protrait;
  13. @property (nonatomic, retain) IBOutlet UIButton *landscapeOneButton;
  14. @property (nonatomic, retain) IBOutlet UIButton *portraitOneButton;
  15. @property (nonatomic, retain) IBOutlet UIButton *landscapeTwoButton;
  16. @property (nonatomic, retain) IBOutlet UIButton *portraitTwoButton;
  17. @end

在Interface Builder中编辑AutoRotationSwapViewController.xib文件,选中AutoRotation SwapViewController.xib窗口中的view,按Delete键将其删除。从Library窗口中拖曳两个View到该窗口中。

选中其中的一个view,然后在名称上面再单击鼠标,将其名称修改为Portrait,用同样方法将另一个view的名称修改为Landscape,如图6-11所示。

 
图6-11  删除原有的view,添加两个新的view并且重新命名

按鼠标右键拖曳File's Owner图标到Portrait图标上,在弹出的Outlets快捷菜单上选择portrait。再拖曳File's Owner图标到Landscape上,和landscape建立Outlet关联,如图6-12所示。

 
图6-12  将Portrait和Landscape建立Outlet关联

再次用鼠标右键拖曳File's Owner图标到Portrait上面,在Outlets快捷菜单上选择view,表明ViewController首先载入的是此view,也就是纵向模式的这个view,如图6-13所示。

 
图6-13  将view与Portrait建立关联

双击Landscape图标,通过快捷键Command+3调整此view的大小,宽度设置为480,高度为300。从Library中拖曳两个Button组件,并修改其Title分别为One和Two,如图6-14所示。

 
(点击查看大图)图6-14  设置Landscape界面

通过File's Owner图标设置One和Two两个按钮的Outlet,分别关联landscapeOneButton和landscapeTwoButton。

双击portrait图标,拖曳两个Button到该view中,Title也分别设置为一和二,同样进行Outlet关联,分别为portraitOneButton和portraitTwoButton,如图6-15所示。

 
(点击查看大图)图6-15  设置portrait界面

关闭Interface Builder返回到Xcode。在AutoRotationSwapViewController.m文件中进行如下修改。

  1. #import "AutoRotationSwapViewController.h"
  2. @implementation AutoRotationSwapViewController
  3. @synthesize landscape;
  4. @synthesize portrait;
  5. @synthesize landscapeOneButton;
  6. @synthesize portraitOneButton;
  7. @synthesize landscapeTwoButton;
  8. @synthesize portraitTwoButton;
  9. - (BOOL)shouldAutorotateToInterfaceOrientation:
  10. (UIInterfaceOrientation)interfaceOrientation {
  11. return YES;
  12. }
  13. - (void)willAnimateRotationToInterfaceOrientation:
  14. (UIInterfaceOrientation) interfaceOrientation
  15. duration:(NSTimeInterval)duration {
  16. if (interfaceOrientation == UIInterfaceOrientationPortrait) {
  17. selfself.view = self.portrait;
  18. self.view.transform = CGAffineTransformIdentity;
  19. self.view.transform = CGAffine
    TransformMakeRotation(degreesToRadians(0));
  20. self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
  21. } else if (interfaceOrientation == 
    UIInterfaceOrientationLandscapeLeft) {
  22. selfself.view = self.landscape;
  23. self.view.transform = CGAffineTransformIdentity;
  24. self.view.transform = 
    CGAffineTransformMakeRotation(degreesToRadians(-90));
  25. self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);
  26. } else if (interfaceOrientation == 
    UIInterfaceOrientationPortraitUpsideDown) {
  27. selfself.view = self.portrait;
  28. self.view.transform = CGAffineTransformIdentity;
  29. self.view.transform = 
    CGAffineTransformMakeRotation(degreesToRadians(180));
  30. self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
  31. } else if (interfaceOrientation == 
    UIInterfaceOrientationLandscapeRight) {
  32. selfself.view = self.landscape;
  33. self.view.transform = CGAffineTransformIdentity;
  34. self.view.transform = 
    CGAffineTransformMakeRotation(degreesToRadians(90));
  35. self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);
  36. }
  37. }
  38. - (void)viewDidUnload {
  39. // Release any retained subviews of the main view.
  40. // e.g. self.myOutlet = nil;
  41. self.portrait = nil;
  42. self.landscape = nil;
  43. self.portraitOneButton = nil;
  44. self.portraitTwoButton = nil;
  45. self.landscapeOneButton = nil;
  46. self.landscapeTwoButton = nil;
  47. [super viewDidUnload];
  48. }
  49. - (void)dealloc {
  50. [portrait release];
  51. [landscape release];
  52. [portraitOneButton release];
  53. [portraitTwoButton release];
  54. [landscapeOneButton release];
  55. [landscapeTwoButton release];
  56. [super dealloc];
  57. }

执行Build and Run命令。在模拟器中纵向模式和横向模式效果如图6-16所示。

 
(点击查看大图)图6-16  模拟器中的运行效果

在这一部分的练习中我们需要两个不同的view以适应不同的显示方向,所以首先在AutoRotationSwapViewController.h文件中定义两个UIView,以及相应的4个UIButton,同时我们还定义了一个宏:

  1. #define degreesToRadians(x) (M_PI * (x) / 180.0)

它帮助我们把角度值转换为弧度值,方便我们在AutoRotationSwapViewController.m文件中进行view的手工旋转。当然手工旋转view时可以直接使用弧度,但是大多数人对于弧度的表象远不如角度直观,所以我们添加了这样的一个宏。

在Interface Builder中我们向AutoRotationSwapViewController.xib里面添加两个新的view。虽然原始的xib中已经含有一个view,但是这个view的大小是不可变的,如图6-17所示。size属性的高度和宽度均为灰色,根本无法修改。所以我们在AutoRotationSwapViewController.xib窗口中删除默认的这个view后再加入两个全新的view。

 
图6-17  添加两个新的view

需要我们注意的是,除了对新添加的两个view分别和portrait与landscape建立Outlet关联以外,还要将AutoRotationSwapViewController.xib自身的view与portrait再次建立Outlet关联,使得该view在启动时就被显示出来。

接下来我们将Landscape view调整为480×300,因为状态条占据20的高,所以这个view的高度就为300。

对AutoRotationSwapViewController.xib的设置完成以后,我们再次返回到Xcode。

首先修改shouldAutorotateToInterfaceOrientation方法,使其返回值为YES,也就意味着该ViewController支持所有方向的屏幕旋转。

然后,增加willAnimateRotationToInterfaceOrientation:duration:方法,这个方法来自于继承的UIViewController类,我们在当前类中重写该方法,并在view开始旋转之前调用这个方法。在这个方法中我们根据参数传递进来的设备旋转的方向设置当前的view是portrait还是landscape。调用了CGAffineTransformMakeRotation方法,CGAffineTransformMakeRotation方法是Core Graphics框架的一部分,它创建一个旋转变形(Rotation Transformation)。变形(Transformation)是通过数学方式表明一个对象的大小、位置和角度的改变。一般来说,iOS在设备被旋转的时候会自动设置变形的值,但是我们在设备旋转的时候更改了当前的view,为了不让这个操作对iOS的自动变形设置产生混乱,我们通过CGAffineTransformMakeRotation方法手动对交换后的view进行旋转变形。

ios View之间的切换 屏幕旋转的更多相关文章

  1. iOS 视图在不同View之间的切换(对于convertRect:函数的一些理解)

    可以通过以下函数完成坐标体系在不同View之间的切换,如下面是完成当前View向ParentView坐标的转换(一个矩阵转换)CGRect parentRect = [currentView conv ...

  2. IOS - view之间切换

    //进入下一页 - (IBAction)Go:(id)sender { TwoViewController *twoVC = [[TwoViewController alloc] init];//这里 ...

  3. iOS 让部分ViewController支持屏幕旋转

    首先,在Xcode里设置整个项目支持的屏幕显示方向: 然后创建一个UINavigationController的子类,然后重载以下属性: 对于需要自定义屏幕方向的ViewController,重载这个 ...

  4. ios UI 之间的切换方法,using prepareForSegue and not

    1, use prepareForSegue: - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { RWTDe ...

  5. OpenGL ES 响应屏幕旋转 iOS

    iOS下使用OpenGL 如果使用GLKit View 那么不用担心屏幕旋转的问题,说明如下: If you change the size, scale factor, or drawable pr ...

  6. OpenGL ES: iOS 自定义 UIView 响应屏幕旋转

    iOS下使用OpenGL 如果使用GLKit View 那么不用担心屏幕旋转的问题,说明如下: If you change the size, scale factor, or drawable pr ...

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

    iTouch,iPhone,iPad设置都是支持旋转的,如果我们的程序能够根据不同的方向做出不同的布局,体验会更好. 如何设置程序支持旋转呢,通常我们会在程序的info.plist中进行设置Suppo ...

  8. AJ学IOS 之控制器view显示中view的父子关系及controller的父子关系_解决屏幕旋转不能传递事件问题

    AJ分享,必须精品 一:效果 二:项目代码 这个Demo用的几个控制器分别画了不通的xib,随便拖拽了几个空间,主要是几个按钮的切换,主要代码展示下: // // NYViewController.m ...

  9. Objective-C ,ios,iphone开发基础:多个视图(view)之间的切换2,使用导航栏控制,以及视图之间传值。

    首先需要说明的是每个应用程序都是一个window,背景色为黑色.在window上可以跑多个view进行来回切换,下面就通过手动写代码来体现导航栏切换view的原理. 第一步,新建一个single vi ...

随机推荐

  1. COGS2085 Asm.Def的一秒

    时间限制:1 s   内存限制:256 MB [题目描述] “你们搞的这个导弹啊,excited!” Asm.Def通过数据链发送了算出的疑似目标位置,几分钟后,成群结队的巡航导弹从“无蛤”号头顶掠过 ...

  2. 将setter方法与itemClick: 进行类比

        https://www.evernote.com/shard/s227/sh/a0c3afa3-8792-4756-8594-d2387a7f57ad/b561ff665af9ad401c8e ...

  3. Docker原理 -- namespace与CGroup

    命名空间 PID(Process ID) 进程隔离 NET(Network) 管理网络隔离 IPC(InterProcess Communication) 管理跨进程通信的访问 MNT(Mount) ...

  4. sql 批量更新表中多字段为不同的值

    ,),,),rand()) select newid() ,) update tablename , FB,)) , ), FC,)) , )

  5. bzoj 2190 线性生成欧拉函数表

    首先我们知道,正方形内个是对称的,关于y=x对称,所以只需要算出来一半的人数 然后乘2+1就行了,+1是(1,1)这个点 开始我先想的递推 那么我们对于一半的三角形,一列一列的看,假设已经求好了第I- ...

  6. eclipse导入java和android sdk源码,帮助文档

    eclipse导入java和android sdk源码,帮助文档 http://blog.csdn.net/ashelyhss/article/details/37993261 JavaDoc集成到E ...

  7. 小苏的Shell编程笔记之六--Shell中的函数

    http://xiaosu.blog.51cto.com/2914416/531247 Shell函数类似于Shell脚本,里面存放了一系列的指令,不过Shell的函数存在于内存,而不是硬盘文件,所以 ...

  8. 【bzoj2086】Blocks

    在洛谷上点了个Splay的tag想玩玩,结果看到这题…… #include<bits/stdc++.h> #define N 1000005 using namespace std; ty ...

  9. CentOS下使用Iptraf进行网络流量的分析笔记

    CentOS下使用Iptraf进行网络流量的分析笔记 一.概述 Iptraf是一款linux环境下,监控网络流量的一款绝佳的免费小软件. 本博客其他随笔参考: Centos安装流量监控工具iftop笔 ...

  10. 【 Zabbix 】— 监控nginx

    一.环境说明 OS:centos6.7 x64 nginx:nginx/1.9.9 ZABBIX:2.4.8 zabbix监控nginx是根据nginx的stub_status模块,抓取status模 ...