苹果的产品iPad和iPhone都是支持自动旋转的,于是咱们写的程序也要支持两种视图:纵向和横向。ide
默认状况下,咱们写的程序都是纵向的,就像前边的几个例子中那样。若是运行之前写的程序,当把模拟器旋转,你会发现很不友好,有的控件看不见了。这个时候,自动旋转就显得颇有必要了。布局
一、咱们先不谈如何实现自动旋转,先讲讲如何让程序知道它支持哪几种旋转。spa
运行Xcode 4.2,新建一个Single View Application,程序名为RotateTest,其余设置以下图:设计
建立好工程后,打开的第一个页面包含以下视图:3d
咱们能够在这里设置程序支持哪一种旋转,只需选中那个按钮。从上图能够看出,默认状况下,iPhone程序不支持倒过来的旋转,由于若是视图是倒过来 的,而此时忽然来电话,那么会很不方便,由于页面依然是倒过来的。可是,若是你建立了一个iPad程序,你回发现上图四个按钮都是选中的,即iPad程序 默认支持全部旋转。code
注意,若是为程序建立了多个View Controller,那么每一个View Controller都要能够设置所支持的旋转,不过,新建的View Controller设置的值必须是主View Controller的子集。orm
其实,咱们修改上图中的按钮,实质上修改的是咱们程序的plist文件,在这个工程中,是RotateTest-Info.plist文件,以下图,展开这个文件,最下面显示的就是所支持的旋转:get
上面是设置支持选中的一种方法。咱们也能够在代码中设定所支持的旋转。打开ViewController.m,找到shouldAutorotateToInterfaceOrientation方法,完整代码以下:虚拟机
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); }
上面的代码代表,不支持倒转(UIInterfaceOrientationPortraitUpsideDown)。页面布局
iOS中定义了四个表示方向的变量:
UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight
若是iOS设置旋转了,程序就会调用这个方向,若是返回YES就旋转视图,不然的话就不旋转。若是你创建了一个iPad程序,这个方法就是简单的返回YES。
二、既然咱们已经让程序知道支持什么旋转了,下面讲讲如何实现。
在iOS中有三种方法能够实现自动旋转。
(1)最简单的方法就是利用Xcode中的Size Inpector:
(2)在View所对应的ViewController.m中重写willAnimateRotationToInterfaceOrientation方法,在这个方法中从新设置控件的大小与位置。
(3)再新建一个视图,这样,咱们有两个视图了,一个纵向,一个横向。在这两个视图上设计好了以后,当旋转时根据旋转方向,调用相应的视图。
三、如下是这三个方法的简单使用。
3.1 使用Size Inpector实现自动旋转:
① 单击ViewController.xib,在打开的视图区域拖放两个Button在上面,分别命名为“按钮上”和“按钮下”,页面布局以下图:
图中两个按钮在水平方向上是居中放置的。
② 运行程序,并将模拟器旋转,对比一下旋转先后的效果:
旋转以后,“按钮下”不见了。不过,“按钮上”的坐标和大小实际上是没变的。
我如今想实现旋转以后两个按钮仍是水平方向居中,而且仍是一个在顶端、一个在底端。为实现这个,我要作如下工做:
③ 在View中选中“按钮上”,打开Size Inspector,把左边的红实线改为虚线:
④ 在View中选中“按钮下”,打开Size Inspector,把左边和上边的红实线改为虚线,下边的红虚线改为实线:
外围的红实线表示距离不变,例如上图右中下方的红实线就表示对应的控件与下方的距离不变,而其余方向会自动调整。如今运行一下并旋转模拟器,看看效果:
3.2 重写willAnimateRotationToInterfaceOrientation方法,从新设置控件的大小与位置
① 首先先给这两个按钮添加Outlet映射到ViewController.h,名称分别是button_1和button_2:
② 在ViewController.m中的@end以前添加如下代码:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval) duration { if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) { button_1.frame = CGRectMake(124, 20, 72, 37); button_2.frame = CGRectMake(124, 403, 72, 37); } else { button_1.frame = CGRectMake(20, 131, 72, 37); button_2.frame = CGRectMake(388, 131, 72, 37); } }
③ 运行,看看效果:
3.3 建立新视图,旋转时切换视图:
① 咱们先建立原始视图的副本,可是仍是在原来的ViewController中。单击ViewController.xib,打开IB,在左边的三个图标中 选中View图标,若是用的是Mac Book,那么按住Control键,若是是虚拟机,请按住Alt键。按住后按住鼠标左键,往下拖,鼠标会变成绿色的加号。注意新视图跟原始图是并列的, 因此你要往正确的方向拖,而后松开鼠标,这样就建立了原来视图的副本:
② 调整新视图为横向(Landscape):
选中新视图,打开Attribute Inspector,在Orientation中选择Landscape:
③ 调整新视图中的按钮的位置,你能够按照本身的喜爱设置,这里设置成以下所示:
④ 下面,咱们为这两个View创建Outlet映射,注意是View,而不是View上的控件。创建映射的方法都是同样,两个名称分别是portrait和landscape:
⑤ 单击ViewController.m,在@implementation那行代码的下一行添加如下语句:
#define degreesToRadians(x) (M_PI*(x)/180.0)
⑥ 修改willAnimateRotationToInterfaceOrientation方法,以下:
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if (toInterfaceOrientation == UIInterfaceOrientationPortrait) { self.view = self.portrait; self.view.transform = CGAffineTransformIdentity; self.view.transform = CGAffineTransformMakeRotation(degreesToRadians(0)); self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0); } else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) { self.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(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) { self.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); } }
⑦ 运行,查看效果:
四、小结
此次讲了实现自动旋转调整大小的三种方法,第一种只要点点鼠标,很简单,但不适合复杂的视图;第二种要从新设置控件的大小和位置,代码量会比较大;第三种是建立两种视图,旋转时调用不一样的视图,比较适合复杂的视图。