ios View之间的切换 屏幕旋转
6.3 View之间的切换
在上面的练习中我们通过移动组件的位置和调整组件的大小来处理横向与纵向的界面布局。但是在界面中有很多组件的时候,对每个组件都进行这样的操作确实是一个麻烦的事情。下面我们看看处理屏幕旋转的第二种方法,在ViewController开始旋转之前进行view的切换。
实战:屏幕旋转时进行view的切换
打开Xcode,创建一个新的Xcode项目,选择View-based 应用程序模板,项目名称为AutoRotationSwap。
修改AutoRotationSwapViewController.h文件。
- #import <UIKit/UIKit.h>
- #define degreesToRadians(x) (M_PI * (x) / 180.0)
- @interface AutoRotationSwapViewController : UIViewController {
- UIView *landscape;
- UIView *portrait;
- UIButton *landscapeOneButton;
- UIButton *portraitOneButton;
- UIButton *landscapeTwoButton;
- UIButton *portraitTwoButton;
- }
- @property (nonatomic, retain) IBOutlet UIView *landscape;
- @property (nonatomic, retain) IBOutlet UIView *protrait;
- @property (nonatomic, retain) IBOutlet UIButton *landscapeOneButton;
- @property (nonatomic, retain) IBOutlet UIButton *portraitOneButton;
- @property (nonatomic, retain) IBOutlet UIButton *landscapeTwoButton;
- @property (nonatomic, retain) IBOutlet UIButton *portraitTwoButton;
- @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文件中进行如下修改。
- #import "AutoRotationSwapViewController.h"
- @implementation AutoRotationSwapViewController
- @synthesize landscape;
- @synthesize portrait;
- @synthesize landscapeOneButton;
- @synthesize portraitOneButton;
- @synthesize landscapeTwoButton;
- @synthesize portraitTwoButton;
- - (BOOL)shouldAutorotateToInterfaceOrientation:
- (UIInterfaceOrientation)interfaceOrientation {
- return YES;
- }
- - (void)willAnimateRotationToInterfaceOrientation:
- (UIInterfaceOrientation) interfaceOrientation
- duration:(NSTimeInterval)duration {
- if (interfaceOrientation == UIInterfaceOrientationPortrait) {
- selfself.view = self.portrait;
- self.view.transform = CGAffineTransformIdentity;
- self.view.transform = CGAffine
TransformMakeRotation(degreesToRadians(0)); - self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
- } else if (interfaceOrientation ==
UIInterfaceOrientationLandscapeLeft) { - selfself.view = self.landscape;
- self.view.transform = CGAffineTransformIdentity;
- self.view.transform =
CGAffineTransformMakeRotation(degreesToRadians(-90)); - self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);
- } else if (interfaceOrientation ==
UIInterfaceOrientationPortraitUpsideDown) { - selfself.view = self.portrait;
- self.view.transform = CGAffineTransformIdentity;
- self.view.transform =
CGAffineTransformMakeRotation(degreesToRadians(180)); - self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
- } else if (interfaceOrientation ==
UIInterfaceOrientationLandscapeRight) { - selfself.view = self.landscape;
- self.view.transform = CGAffineTransformIdentity;
- self.view.transform =
CGAffineTransformMakeRotation(degreesToRadians(90)); - self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 300.0);
- }
- }
- - (void)viewDidUnload {
- // Release any retained subviews of the main view.
- // e.g. self.myOutlet = nil;
- self.portrait = nil;
- self.landscape = nil;
- self.portraitOneButton = nil;
- self.portraitTwoButton = nil;
- self.landscapeOneButton = nil;
- self.landscapeTwoButton = nil;
- [super viewDidUnload];
- }
- - (void)dealloc {
- [portrait release];
- [landscape release];
- [portraitOneButton release];
- [portraitTwoButton release];
- [landscapeOneButton release];
- [landscapeTwoButton release];
- [super dealloc];
- }
执行Build and Run命令。在模拟器中纵向模式和横向模式效果如图6-16所示。
|
| (点击查看大图)图6-16 模拟器中的运行效果 |
在这一部分的练习中我们需要两个不同的view以适应不同的显示方向,所以首先在AutoRotationSwapViewController.h文件中定义两个UIView,以及相应的4个UIButton,同时我们还定义了一个宏:
- #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之间的切换 屏幕旋转的更多相关文章
- iOS 视图在不同View之间的切换(对于convertRect:函数的一些理解)
可以通过以下函数完成坐标体系在不同View之间的切换,如下面是完成当前View向ParentView坐标的转换(一个矩阵转换)CGRect parentRect = [currentView conv ...
- IOS - view之间切换
//进入下一页 - (IBAction)Go:(id)sender { TwoViewController *twoVC = [[TwoViewController alloc] init];//这里 ...
- iOS 让部分ViewController支持屏幕旋转
首先,在Xcode里设置整个项目支持的屏幕显示方向: 然后创建一个UINavigationController的子类,然后重载以下属性: 对于需要自定义屏幕方向的ViewController,重载这个 ...
- ios UI 之间的切换方法,using prepareForSegue and not
1, use prepareForSegue: - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { RWTDe ...
- OpenGL ES 响应屏幕旋转 iOS
iOS下使用OpenGL 如果使用GLKit View 那么不用担心屏幕旋转的问题,说明如下: If you change the size, scale factor, or drawable pr ...
- OpenGL ES: iOS 自定义 UIView 响应屏幕旋转
iOS下使用OpenGL 如果使用GLKit View 那么不用担心屏幕旋转的问题,说明如下: If you change the size, scale factor, or drawable pr ...
- 【转】IOS屏幕旋转与View的transform属性之间的关系,比较底层
iTouch,iPhone,iPad设置都是支持旋转的,如果我们的程序能够根据不同的方向做出不同的布局,体验会更好. 如何设置程序支持旋转呢,通常我们会在程序的info.plist中进行设置Suppo ...
- AJ学IOS 之控制器view显示中view的父子关系及controller的父子关系_解决屏幕旋转不能传递事件问题
AJ分享,必须精品 一:效果 二:项目代码 这个Demo用的几个控制器分别画了不通的xib,随便拖拽了几个空间,主要是几个按钮的切换,主要代码展示下: // // NYViewController.m ...
- Objective-C ,ios,iphone开发基础:多个视图(view)之间的切换2,使用导航栏控制,以及视图之间传值。
首先需要说明的是每个应用程序都是一个window,背景色为黑色.在window上可以跑多个view进行来回切换,下面就通过手动写代码来体现导航栏切换view的原理. 第一步,新建一个single vi ...
随机推荐
- IDEA新建时选项没有java class问题
解决办法: 点击你的project F4打开project stucture 点击左边的module 点击右边的source后添加src就可以了 添加的src就是源码可以放置的地址
- Spring - IoC(3): Bean 实例的创建方式
创建一个 Bean 实例对象的方法通常有如下方式: 调用构造器创建 Bean 实例 调用静态工厂方法创建 Bean 实例 调用实例工厂方法创建 Bean 实例 使用构造器创建 Bean 实例 XML ...
- 【mysql优化】大数据量分页优化
limit 翻页原理 limit offset,N, 当offset非常大时, 效率极低, 原因是mysql并不是跳过offset行,然后单取N行, 而是取offset+N行,返回放弃前offset行 ...
- wx.ScrolledWindow wx.PseudoDC
# encoding: utf-8 import logging import random import wx import wx.lib.inspection def GetMyBitmap(): ...
- 关于一些Java基础数据类型的常用方法的应用场景的小思考
昨天遇到一个问题,按照我的一半解决方法是传一个参数,然后通过参数来控制逻辑处理:但是领导发现String的一个方法也可以完全完成该问题!而我完全没有get到这个点! so,我认识到了自己的知识盲区:基 ...
- ORM- 图书系统查询
图书信息系统 表结构设计 # 书 class Book(models.Model): title = models.CharField(max_length=32) publish_date = mo ...
- hdu 5184(数学-卡特兰数)
Brackets Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- Python 进阶 之 yield
.转载自:https://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/ Python yield 使用浅析: 您可能听说过, ...
- 转载 Ofbiz 入门教程
1.Ofbiz 介绍: Ofbiz(http://www.ofbiz.org) 是 Open Source 的商务软件系统,充分利用了各优秀的的Open Source 项目,像 Tomcat, Ant ...
- LayerDate渲染多个class出现闪现问题的解决
填写表单的时候有时候会需要添加一行表单的业务逻辑,而表单要用到LayerDate的话便不可避免的出现多个class的情况 这种情况下后面的class是无法渲染的,layerDate官网提出了解决方法: ...