现在的位置: 首页 > 综合 > 正文

屏幕旋转

2017年08月04日 ⁄ 综合 ⁄ 共 3237字 ⁄ 字号 评论关闭

在iphone官方提供的应用中,有一个计算器应用,竖屏时它是一个简单的计算器;横屏时,它是一个复杂的科学计算器。


从这个计算器应用可以看出,横屏和竖屏时分别采用了不同的视图,而不是同一个视图界面元素的重新布局。这里我们的sample中,竖屏时屏幕中有3个按钮,横屏时屏幕中有4个按钮。


这里我们把创建工程时生成的视图作为竖屏,那么我们需要额外创建一个横屏视图。我们有3种方式来实现横屏视图:

1、创建一个视图的xib文件,并使用Interface Builder涉及这个xib文件,然后从xib文件实例化视图对象。

2、创建一个带xib文件的视图控制器,并使用Interface Builder设计这个xib文件,通过initWithNibName:bundle:构造函数实例化视图控制器,然后通过视图控制器的view属性获得视图对象。

3、创建一个storyboard和一个视图控制器,并使用Interface Builder设计这个storyboard文件,通过storyboard的storyboardWithName:bundle:方法实例化视图控制器,然后通过视图控制器的view属性获得视图对象。

这里我们采用视图控制器和storyboard,内存管理采用ARC。


ViewController.h相关代码:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@property (nonatomic,strong) UIView *portraitView;
@property (nonatomic,strong) UIView *landscapeView;

@end

这里我们定义了横屏和竖屏的视图属性。


ViewController.m相关代码:

#import "ViewController.h"
#import "LandscapeViewController.h"

#define deg2rad (M_PI/180)
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    LandscapeViewController *landscapeViewController=[[UIStoryboard storyboardWithName:@"LandscapeStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:@"LandscapeViewController"];
    self.landscapeView=landscapeViewController.view;
    self.portraitView=self.view;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{   
    if(toInterfaceOrientation==UIDeviceOrientationLandscapeRight){
        self.view.transform=CGAffineTransformMakeRotation(deg2rad*(-90.0));
        self.view.bounds=CGRectMake(0.0, 20.0, 568.0, 300.0);
    }else if(toInterfaceOrientation==UIDeviceOrientationLandscapeLeft){
        self.view=self.landscapeView;
        self.view.transform=CGAffineTransformMakeRotation(deg2rad*90.0);
        self.view.bounds=CGRectMake(0.0, 20.0, 568.0, 300.0);
    }else{//portrait
        self.view=self.portraitView;
        self.view.transform=CGAffineTransformMakeRotation(deg2rad*0.0);
        self.view.bounds=CGRectMake(0.0, 20.0, 320.0, 548.0);
    }
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

在viewDidLoad方法中,我们先获取横屏storyboard,然后再用此对象实例化横屏视图控制器,最后获取横屏视图控制器的view属性值,即横屏view。由于初始界面是竖屏,所以竖屏view就是当前的view。


shouldAutorotate方法用于指定当前视图是否支持旋转。

supportedInterfaceOrientations方法指定视图支持哪个方向的旋转。在iPad中,该方法的返回值默认是UIInterfaceOrientationMaskAll,表示支持所有方向旋转。在iPhone中,其返回值默认是UIInterfaceOrientationMaskAllButUpsideDown,支持除了竖直向下以外的其他3个方向。视图支持某个方向的前提是设备也支持该方向。

willAnimateRotationToInterfaceOrientation:duration:方法在屏幕旋转之前触发,其参数toInterfaceOrientation可以判断屏幕的旋转方向,是枚举UIInterfaceOrientation中定义的常量。UIInterfaceOrientation在UIApplication.h中定义:

// Note that UIInterfaceOrientationLandscapeLeft is equal to UIDeviceOrientationLandscapeRight (and vice versa).
// This is because rotating the device to the left requires rotating the content to the right.
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
    UIInterfaceOrientationPortrait           = UIDeviceOrientationPortrait,
    UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
    UIInterfaceOrientationLandscapeLeft      = UIDeviceOrientationLandscapeRight,
    UIInterfaceOrientationLandscapeRight     = UIDeviceOrientationLandscapeLeft
};

需要注意的是,在判断向某个方向旋转时,不仅要将旋转的视图替换为当前视图,还要把视图进行旋转变换并重新调整视图的边界


上述代码中,CGAffineTransformMakeRotation函数是放射变换函数,用于视图的二维坐标变换,类似的还有缩放和位移放射变换函数,其中的参数是弧度。







抱歉!评论已关闭.