iphone旋转响应的方法

来源:互联网 发布:看不起同学知乎 编辑:程序博客网 时间:2024/05/18 21:47

我们都知道,在iPhone/iPad应用程序开发中会涉及到旋转问题,当 然,旋转问题的处理在某方面来说是比较烦的工作,这倒不是因为有多复杂,只是不太好控制。特别时xib和代码同时进行操作将会使问题更加复杂话。所以在进 行旋转处理时的第一点建议就时尽量采取xib或者代码操作中的一种,不到万不得已就不要两种方式同时使用了。当然其实对与这样的事情是没什么万不得已的。


旋转控制的第一步就是必须要让你的应用支持旋转功能,为了保证自己的代码能够支持旋转,我们必须首先处理一个函数:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return YES;
}

这个函数时用来确定我们的应用所支持的旋转方向。如果想要支持每个方向则直接返回YES就行。完成了这一步,我们就可以根据所支持的方向来处理旋转问题了。这里我们首先来看看可以用来支持旋转的函数:

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
}
-(void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
}
-(void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation duration:(NSTimeInterval)duration {
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
}
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
}
-(void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
}

这些函数,都可以用来支持旋转,当然这些旋转函数中存在这一定的相互制约关系,亦即有些旋转函数是不能同时存在的(这只是我在做的过程中所遇到的,具体怎样一种制约关系这里就不说了)。


接下来就我们将开始旋转处理的问题了,在具体到每一个函数之前,先说一个问 题,就是关于各种view的自动适应问题,前面说过尽量保证不要在xib和代码中同时处理,这里还要说一下,如果要手动控制位置的话也不要通过代码设置自 适应大小,如果这样可能会导致支持旋转的函数在设置好位置后有因为自适应而再次对大小进行调整而造成不可控制。


接下来可以来探讨上面的几个函数的用法了。

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
}

这个函数,执行在旋转方向发生改变时,但有个问题,自己多次对这个函数进行测试,其frame都是以竖屏方式,只是他的statusBarOrientation的方向发生了变化。其方向与将要旋转到的方向时保持一致的。

对于其他的函数自己可以通过输出statusBarOrientation和frame的方式来获知其执行时间当然还可以和其他几个支持旋转的函数一起配合着使用来知道其执行顺序。

下面该说 说对旋转的处理了,由于每个支持旋转的函数在其执行是的方向和frame的不同我们就必须根据我们的需要来确定了,甚至在某些函数下不能通过 self.view的frame的参数值来设置,因为在旋转过程中self.view的frame值是不可靠的。所以我们可以通过设置定值的方式来处理, 但是这种方式并不方便。不过对于特定的处理是比较可靠的。

对于要处 理的东西特别多的我们可以通过继承的方式来实现,通过把子view放在继承中实现,并通过在子view中实现layoutSubviews函数来实现旋转 后的位置布局是比较好的。但是这里要说明,如果我们要是调整的位置可控建议不要在使用继承下来的类中对该类的view使用自适应方式,而通过在旋转的函数 中来设置其frame的大小,这样就可以保证在我们自定义类的对向在我们想要的时刻来调整他的frame。若时设置了只适应大小,这将导致我们 layoutSubviews函数并不一定时在我们调整了他的frame之后才执行,而是在它通过自适应方式调整了大小之后就执行。


这六个方法在模拟器不是都能用的,仅1,4,5可用

1.willAnimateRotationToInterfaceOrientation:该方法将在视图旋转开始/旋转动画发生之前自动调用

2.willAnimateFirstHalfOfRotationToInterfaceOrientation在视图旋转动画前一半发生之前自动调用

3.willAnimateSecondHalfOfRotationFromInterfaceOrientation在视图旋转动画后一半发生之前自动调用

4.willRotateToInterfaceOrientation:该方法将在视图旋转之前自动调用

5.didRotateFromInterfaceOrientation:该方法将在视图旋转完成之后自动调用

6.didAnimateFirstHalfOfRotationToInterfaceOrientation该方法将在视图旋转动画前一半发生之后自动调用


typedefenum {

    UIInterfaceOrientationPortrait           =UIDeviceOrientationPortrait,

    UIInterfaceOrientationPortraitUpsideDown =UIDeviceOrientationPortraitUpsideDown,

    UIInterfaceOrientationLandscapeLeft      =UIDeviceOrientationLandscapeRight,

    UIInterfaceOrientationLandscapeRight     =UIDeviceOrientationLandscapeLeft

} UIInterfaceOrientation;


#define UIDeviceOrientationIsValidInterfaceOrientation(orientation) ((orientation) == UIDeviceOrientationPortrait || (orientation) == UIDeviceOrientationPortraitUpsideDown || (orientation) == UIDeviceOrientationLandscapeLeft || (orientation) == UIDeviceOrientationLandscapeRight)

#define UIInterfaceOrientationIsPortrait(orientation)  ((orientation) == UIInterfaceOrientationPortrait || (orientation) == UIInterfaceOrientationPortraitUpsideDown)

#define UIInterfaceOrientationIsLandscape(orientation) ((orientation) == UIInterfaceOrientationLandscapeLeft || (orientation) == UIInterfaceOrientationLandscapeRight)




UIDeviceOrientation 和 UIInterfaceOrientation 设备旋转的用法 (实例)

    博客分类: 
  • IOS / Objective-C
 

UIDeviceOrientation      是机器硬件的当前旋转方向   这个你只能取值 不能设置

UIInterfaceOrientation   是你程序界面的当前旋转方向   这个可以设置

 

判断设备现在的方向:

C代码  收藏代码
  1. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
  2. {  
  3.     //宣告一個UIDevice指標,並取得目前Device的狀況  
  4.     UIDevice *device = [UIDevice currentDevice] ;   
  5.       
  6.     //取得當前Device的方向,來當作判斷敘述。(Device的方向型態為Integer)  
  7.     switch (device.orientation) {  
  8.         case UIDeviceOrientationFaceUp:  
  9.         NSLog(@"螢幕朝上平躺");  
  10.             break;  
  11.               
  12.         case UIDeviceOrientationFaceDown:  
  13.         NSLog(@"螢幕朝下平躺");  
  14.             break;  
  15.               
  16.         //系統無法判斷目前Device的方向,有可能是斜置   
  17.         case UIDeviceOrientationUnknown:  
  18.         NSLog(@"未知方向");  
  19.             break;  
  20.               
  21.         case UIDeviceOrientationLandscapeLeft:  
  22.         NSLog(@"螢幕向左橫置");  
  23.             break;  
  24.               
  25.         case UIDeviceOrientationLandscapeRight:  
  26.         NSLog(@"螢幕向右橫置");  
  27.             break;  
  28.               
  29.         case UIDeviceOrientationPortrait:  
  30.         NSLog(@"螢幕直立");  
  31.             break;  
  32.               
  33.         case UIDeviceOrientationPortraitUpsideDown:  
  34.         NSLog(@"螢幕直立,上下顛倒");  
  35.             break;  
  36.               
  37.         default:  
  38.         NSLog(@"無法辨識");  
  39.             break;  
  40.     }  
  41.   
  42.     // Return YES for supported orientations  
  43.     return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft); // 只支持向左横向, YES 表示支持所有方向  
  44. }  
 

或者

C代码  收藏代码
  1. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  
  2. {  
  3.     UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;  
  4.     if (UIDeviceOrientationIsLandscape(deviceOrientation)) NSLog(@"横向");      
  5.     else if(UIDeviceOrientationIsPortrait(deviceOrientation)) NSLog(@"纵向");  
  6.       
  7.     // // Return YES for supported orientations  
  8.     return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft); // 只支持向左横向, YES 表示支持所有方向  
  9. }  

 

Portrait 表示 纵向,Landscape 表示 横向。

 

C代码  收藏代码
  1. typedef enum {  
  2.     UIDeviceOrientationUnknown,  
  3.     UIDeviceOrientationPortrait,            // Device oriented vertically, home button on the bottom  
  4.     UIDeviceOrientationPortraitUpsideDown,  // Device oriented vertically, home button on the top  
  5.     UIDeviceOrientationLandscapeLeft,       // Device oriented horizontally, home button on the right  
  6.     UIDeviceOrientationLandscapeRight,      // Device oriented horizontally, home button on the left  
  7.     UIDeviceOrientationFaceUp,              // Device oriented flat, face up  
  8.     UIDeviceOrientationFaceDown             // Device oriented flat, face down  
  9. } UIDeviceOrientation;  
 
C代码  收藏代码
  1. typedef enum {  
  2.     UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,  
  3.     UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,  
  4.     UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,  
  5.     UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft  
  6. } UIInterfaceOrientation;  
  
C代码  收藏代码
  1. #define UIDeviceOrientationIsPortrait(orientation)  ((orientation) == UIDeviceOrientationPortrait || (orientation) == UIDeviceOrientationPortraitUpsideDown)  
  2. #define UIDeviceOrientationIsLandscape(orientation) ((orientation) == UIDeviceOrientationLandscapeLeft || (orientation) == UIDeviceOrientationLandscapeRight)  
 

上面是重要的源代码,已经解释的非常清楚。UIDeviceOrientationIsPortrait(orientation) 跟  ((orientation) == UIDeviceOrientationPortrait || (orientation) == UIDeviceOrientationPortraitUpsideDown) 完全是一个意思。





/*****************************************************************************************************************************************************************************/

IPhone的自动旋转功能一共有3中方法

IPhone的自动旋转功能一共有3中方法:

1.使用自动调整属性处理旋转。

利用系统自动生成的代码。

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);//系统默认不支持旋转功能
}

要想让系统自动实现旋转功能仅需要实现上面的代码,把return (interfaceOrientation == UIInterfaceOrientationPortrait)修改成为return OK即可。

修改后的代码为:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return OK;
}

然后在使用自动调整属性设计界面(Apple+3),指定要支持的方向即可。

在使用模拟仿真器的时候,要让其自动旋转只需Apple+ ->(<-)即可。

 

2.在旋转是重构视图。(也即手动设置每一个控件的位置和大小,让其重新排列)

第一种方法基本上不需要编写代码,这种方法就需要写点代码了,毕竟重新设置每一个控件的坐标了嘛。

下面以我弄的一个为例子,例子的名称为IP_05Autosize。

例如,首先看这个图片:

《Iphone开发基础教程》第五章 <wbr>自动旋转和调整大小

在View中添加6个button,然后设定W和H分别为125和125,这样在横向的时候这三个button是会重叠的,因为在横向的时候Iphone支持的显示像素为480x300,没有状态栏的情况下是480x320.(在纵向时候显示像素为320x460,没有状态栏的情况下是320x480)。

现在就需要写代码重新排列这六个按钮了。

首先声明变量:

在IP_05AutosizeViewController.h中添加如下的代码:

#import <UIKit/UIKit.h>

@interface IP_05AutosizeViewController : UIViewController {
 IBOutlet UIButton *button1;
 IBOutlet UIButton *button2;
 IBOutlet UIButton *button3;
 IBOutlet UIButton *button4;
 IBOutlet UIButton *button5;
 IBOutlet UIButton *button6;
}
@property (nonatomic,retain)UIView *button1;
@property (nonatomic,retain)UIView *button2;
@property (nonatomic,retain)UIView *button3;
@property (nonatomic,retain)UIView *button4;
@property (nonatomic,retain)UIView *button5;
@property (nonatomic,retain)UIView *button6;

@end

然后在IP_05AutosizeViewController.m中,添加实现方法。

@implementation IP_05AutosizeViewController
@synthesize button1;
@synthesize button2;
@synthesize button3;
@synthesize button4;
@synthesize button5;
@synthesize button6;

-(void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation duration:(NSTimeInterval)duration
{
 UIInterfaceOrientation to=self.interfaceOrientation;
 if(to == UIInterfaceOrientationPortrait || to == UIInterfaceOrientationPortraitUpsideDown)
 {
  button1.frame = CGRectMake(20, 20, 125, 125);
  button2.frame = CGRectMake(175, 20, 125, 125);
  button3.frame = CGRectMake(20, 168, 125, 125);
  button4.frame = CGRectMake(175, 168, 125, 125);
  button5.frame = CGRectMake(20, 315, 125, 125);
  button6.frame = CGRectMake(175, 315, 125, 125);
 }
 else
 {
  button1.frame = CGRectMake(20, 20, 125, 125);
  button2.frame = CGRectMake(20, 155, 125, 125);
  button3.frame = CGRectMake(177, 20, 125, 125);
  button4.frame = CGRectMake(177, 155, 125, 125);
  button5.frame = CGRectMake(328, 20, 125, 125);
  button6.frame = CGRectMake(328, 155, 125, 125);
 }

}

还需要修改- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation的代码:

修改后为:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

{
   return (interfaceOrientation == UIInterfaceOrientationPortrait
   || interfaceOrientation == UIInterfaceOrientationLandscapeLeft
   || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

然后在dealloc中释放资源:

- (void)dealloc

{
 [button1 release];
 [button2 release];
 [button3 release];
 [button4 release];
 [button5 release];
 [button6 release];
 [super dealloc];
}

到此代码部分搞定,然后就是连接控制器和视图了。这点应该比较简单了。呵呵!

然后Build and Go最终结果为:

《Iphone开发基础教程》第五章 <wbr>自动旋转和调整大小

 

3.切换视图

这种方法使用于比较复杂的界面,是需要分别设计横向模式和纵向模式,然后在使用的过程中自动切换。

当然了这个也需要确定输出口和一些方法了。

首先定义输出口:

(简单描述,设计两个视图,一个定义为landscape,一个是portrait,一个为320x460,一个为480x300,每一个输出口分别和每个视图中的按钮想关联)

//用于切换的两个View

 IBOutlet UIView *landscape;
 IBOutlet UIView *portrait;
 //Foo两个View中的Foo按钮
 IBOutlet UIButton *landscapeFooButton;
 IBOutlet UIButton *portraitFooButton;
 //Bar两个View中的Bar按钮
 IBOutlet UIButton *landscapeBarButton;
 IBOutlet UIButton *portraitBarButton;

还需要File's Owner和两个View想关联。按住Ctrl将File's Owner拖到Portrait上面,在弹出灰色菜单上选择Portrait同理选择Landscape。然后在按住Ctrl将File's Owner拖到Landscape上面,在弹出的灰色菜单上选择View,让Landscape为自启动View。

然后是方法的实现:
-(void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)to duration:(NSTimeInterval)duration
{
 if(to == UIInterfaceOrientationPortrait)
 {
  self.view = self.portrait;
  self.view.transform = CGAffineTransformIdentity;
  self.view.transform = CGAffineTransformMakeRotation(degressToRadian(0));
  self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
 }
 else if (to == UIInterfaceOrientationLandscapeLeft)
 {
  self.view = self.landscape;
  self.view.transform = CGAffineTransformIdentity;
  self.view.transform = CGAffineTransformMakeRotation(degressToRadian(-90));
  self.view.bounds = CGRectMake(0.0, 0.0, 460.0, 320.0);
  
 }
 else if (to == UIInterfaceOrientationPortraitUpsideDown)
 {
  self.view = self.portrait;
  self.view.transform = CGAffineTransformIdentity;
  self.view.transform = CGAffineTransformMakeRotation(degressToRadian(180));
  self.view.bounds = CGRectMake(0.0, 0.0, 320.0, 460.0);
  
 }
 else if (to == UIInterfaceOrientationLandscapeRight)
 {
  self.view = self.landscape;
  self.view.transform = CGAffineTransformIdentity;
  self.view.transform = CGAffineTransformMakeRotation(degressToRadian(90));
  self.view.bounds = CGRectMake(0.0, 0.0, 460.0, 320.0);
  
 }

}

 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

{

       return YES;
}

不要忘了在dealloc中释放资源哦。

因为在上面的代码中使用到了Core Graphics框架,因此要把该框架连接到该项目中,具体的方法是:在Resources上面点右键Add->Existing Frameworks。然后就是查找路径了。我第一次就看错了没有找到,哎,做事情不下心呀!具体路径为:/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator2.2.1.sdk/System/Library/Frameworks/CoreGraphics.framework 呵呵,这个路径是有点长不好找,记住不是在:/Developer/SDKs里面了,我刚开始就是找到呢里面了。呵呵!还有就是导入后会处理一个提示框,不要Copy,Reference Type要选择Relative to Current SDK然后add就OK了。

例子中还有一个方法是对View中的按钮实现隐藏的,这个就比较简单了!

具体方法为:

-(IBAction)buttonPressed:(id)sender
{
 if(sender == portraitFooButton||sender == landscapeFooButton)
 {
  portraitFooButton.hidden=YES;
  landscapeFooButton.hidden=YES;
 }
 else
 {
  portraitBarButton.hidden=YES;
  landscapeBarButton.hidden=YES;
 }

}

呵呵,上图两张看看:

刚开始运行时的图片

《Iphone开发基础教程》第五章 <wbr>自动旋转和调整大小

旋转后并且按了Foo按钮后的图片

《Iphone开发基础教程》第五章 <wbr>自动旋转和调整大小

 

想下载源代码的还去我的CSDN上面下载好了具体地址为:http://hanyegudeng.download.csdn.net/

欢迎指点!


原创粉丝点击