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. [BZOJ1040] [ZJOI2008]骑士 解题报告

    Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火 ...

  2. [BZOJ1004] [HNOI2008]Cards解题报告(Burnside引理)

    Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Sun有多少种染色方案,Sun很快就给出了答案.进一步,小春要求染出Sr张红 ...

  3. 【BZOJ】1579: [Usaco2009 Feb]Revamping Trails 道路升级

    [算法]分层图最短路 [题解] 考虑k层一模一样的图,然后每个夹层都在每条边的位置新加从上一层跨越到下一层的边权为0的边,这样至多选择k条边置为0. 然后考虑方便的写法. SPFA 第一次SPFA计算 ...

  4. python函数篇:名称空间、作用域和函数的嵌套

    一.名称空间:(有3类) (1)内置名称空间(全局作用域) (2)全局名称空间(全局作用域) (3)局部名称空间(局部作用域) 关于名称空间的查询: x=1 def func(): print('fr ...

  5. 【POI2017||bzoj4726】Flappy Birds

    外国人很良心的啊,这题比NOIP那题还简单…… 不用管他最后的位置,因为移动的次数肯定是恒定的,所以维护在每一个柱子的位置能飞到的范围,递推下去即可. #include<bits/stdc++. ...

  6. 2.docker容器

    docker run 镜像,生成镜像容器,并运行 有以下参数 --name="new name",为容器指定一个新名字 -d:后台运行容器,返回容器id,即启动守护式容器 -i:以 ...

  7. 【 Tomcat 】后端tomcat获取真实IP

    环境: nginx + tomcat nginx.conf 配置: proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_ad ...

  8. Grunt环境搭建及使用 前端必备

    jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发人员,如果你现在还不知道grunt或者听说过 ...

  9. SPOJ-913

    Query on a tree II Time Limit: 433MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Su ...

  10. python的上下文管理(contextlib)(2)

    contextlib是一个Python模块,作用是提供更易用的上下文管理器. 编写 __enter__ 和 __exit__ 仍然很繁琐,因此Python的标准库 contextlib 提供了更简单的 ...