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. BZOJ 2095: [Poi2010]Bridges

    2095: [Poi2010]Bridges Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 869  Solved: 299[Submit][Stat ...

  2. Linux make命令详解

    在linux环境下的工作,免不了需要经常编译C/C++源代码,所以make命令是我们经常都会用到的.当然make工具不一定针对C代码,它也可以维护其他各种代码,详见:man make    在列举其详 ...

  3. javascript三种嵌入方式

    什么是JavaScript? JavaScript是运行在浏览器端的脚步语言,JavaScript主要解决的是前端与用户交互的问题,包括使用交互与数据交互,JavaScript是浏览器解释执行的. J ...

  4. 在什么情况下Java比C++快?

    转载   http://www.importnew.com/16056.html

  5. java两种实现二分查找方式

    二分查找法适用于 升序排列的数组,如果你所要操作的数组不是升序排序的,那么请用排序算法,排序一下. 说明:使用二分查找法相比顺序查找  节约了时间的开销,但是增加了空间使用.因为需要动态记录 起始索引 ...

  6. AC日记——[Sdoi2008]Cave 洞穴勘测 bzoj 2049

    2049 思路: lct模板: 代码: #include <cstdio> #include <cstring> #include <iostream> #incl ...

  7. [解决] win7能上网,ubuntu14.04不行

    更新驱动 http://www.realtek.com.tw/downloads/downloadsView.aspx?Langid=1&PNid=13&PFid=5&Leve ...

  8. (14)python 文件和流

    打开文件 f=open('C:\Temp.txt') 读取数据 f.read(); 关闭文件 f.close();#关闭后将无法再读取 打开文件的方式 不写模式,默认是只读模式 1.r 打开只读文件, ...

  9. Codeforces 1039A. Timetable

    题目地址:http://codeforces.com/problemset/problem/1039/A 题目的关键在于理清楚思路,然后代码就比较容易写了 对于每一个位置的bus,即对于每一个i(i& ...

  10. 线段树+扫描线【p1884】[Usaco12FEB]过度种植(银)Overplanting …

    Description 在一个笛卡尔平面坐标系里(则X轴向右是正方向,Y轴向上是正方向),有\(N(1<=N<=1000)\)个矩形,第i个矩形的左上角坐标是\((x1, y1)\),右下 ...