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. 【BZOJ4657】tower [网络流]

    炮塔 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output 一行一个整数表示答案. Sample Input 4 5 0 ...

  2. 【bzoj4810】由乃的玉米田

    lxl丧心病狂-- 首先允许离线的区间询问一看就是莫队.那么我们看下怎么莫队? 不会. "由乃题多半是不可做的."于是我看了下题解--好吧果然是bitset 用bitset维护当前 ...

  3. HCharts的y轴保留一位和 两位小数

    保留一位小数,有一位小数的不变 yAxis : { labels : {  formatter : function () { var strVal = ''+this.value ; if (str ...

  4. nginx之旅:安装及简单部署

    安装之前最好了解一下nginx,参考nginx百度百科吧,下面这一句话基本概括了nginx的基本功能 Nginx ("engine x") 是一个高性能的 HTTP 和 反向代理  ...

  5. css样式表中的样式覆盖顺序(转)

    有时候在写CSS的过程中,某些限制总是不起作用,这就涉及了CSS样式覆盖的问题,如下 Css代码   #navigator { height: 100%; width: 200; position:  ...

  6. [BZOJ4520][Cqoi2016]K远点对 kd-tree 优先队列

    4520: [Cqoi2016]K远点对 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1285  Solved: 708[Submit][Statu ...

  7. 关闭浏览器session就被干掉的假象的问题

    当在前台取出session时,关闭浏览器后再次访问服务器,这时服务器返回了一个null,此时的返回的session并非之前的那个session而是一个新的session. -->先来看看sess ...

  8. 使用graphql和apollo client构建react web应用

    graphql是一种用于 API 的查询语言(摘自官网). 我们为什么要用graphql? 相信大家在开发web应用的时候常常会遇到以下这些问题:后端更新了接口却没有通知前端,从而导致各种报错:后端修 ...

  9. 【LeetCode刷题】SQL-Combine Two Tables

    Table: Person +-------------+---------+ | Column Name | Type | +-------------+---------+ | PersonId ...

  10. 并查集&线段树&树状数组&排序二叉树

    超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...