IOS开发 - 全局竖屏个别横屏的屏幕旋转问题

转载:原文链接

背景:app需求是整个app都竖屏显示,但是其中视频页面需要横屏显示,app的架构:自定义了一个导航栏控制器,自定义一个BaseViewController控制器,所有的控制器都继承自这个BaseVC

1,全局控制

你的应用是否支持屏幕旋转需要一个全局的配置,在 AppDelegate 中有这样一个方法,这个方法返回你的app支持屏幕旋转的全局配置,当某一个viewController要判断是否旋转自己的时候,会调用这个方法,根据这个方法的返回值决定是否可以进行屏幕旋转。
我们一般都是在Info.plist中来配置支持的屏幕旋转的方向的。
一般情况下,程序启动时候的方向是,plist中配置的第一个选项,所以,这里的第一个一般都是竖屏的。

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window

Info.plist 设置 如图所示:

20151109223836428-2.png

2,如果根控制器是Navi控制器,需要这样写:

//注意如果你window的rootViewController是一个navigationController,可能会出现以下问题:
//你的navigationController只支持竖屏,但是你push到了某个新的controller中,这个controller支持横竖屏,当你在新的controller中切换到横屏后(也有可能在切换到横屏然后pop回来后),这时候程序会闪退,因为你的navigationController不支持横屏。
//如果你想解决这个问题,就需要自己写一个UINavigationController的子类,在这个类中重写以下方法:
//返回当前正在显示的控制器是否支持屏幕旋转
- (BOOL)shouldAutorotate
{
    return [self.viewControllers.lastObject shouldAutorotate];
}
// 返回当前正在显示的控制器支持的屏幕旋转方向
- (NSUInteger)supportedInterfaceOrientations
{
    return [self.viewControllers.lastObject supportedInterfaceOrientations];
}
// 返回当前正在显示的控制器,最佳的屏幕方向
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [self.viewControllers.lastObject preferredInterfaceOrientationForPresentation];
}

3,在需要支持屏幕旋转的控制器中

// 判断这个viewController是否支持屏幕旋转
- (BOOL)shouldAutorotate
{
    return YES;
}
 
// 设置手机屏幕支持旋转的方向
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait |
    UIInterfaceOrientationMaskLandscapeLeft |UIInterfaceOrientationMaskLandscapeRight;
}
 
// 手机支持屏幕旋转,并且屏幕已经旋转的时候,会调用这个方法,在这个方法里面,可以重新给view布局以适应不同的屏幕方向
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    NSLog(@"横屏模式");
    NSLog(@"%lf, %lf", ScreenWidth, ScreenHeight);
    
    if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
    {
        NSLog(@"UIInterfaceOrientationLandscapeLeft");
        realScreenWidth = ScreenSize.height;
        realScreenHeight = ScreenSize.width;
    }
    else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
    {
        NSLog(@"UIInterfaceOrientationLandscapeRight");
        realScreenWidth = ScreenSize.height;
        realScreenHeight = ScreenSize.width;
    }
    else if (toInterfaceOrientation == UIDeviceOrientationPortrait)
    {
        NSLog(@"UIDeviceOrientationPortrait");
        realScreenWidth = ScreenSize.width;
        realScreenHeight = ScreenSize.height;
    }
    
    [self reloadScroll];
}

4,在所有控制器的父控制器中

// 支持设备自动旋转
- (BOOL)shouldAutorotate
{
    return NO;
}
 
// 支持竖屏显示
- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

写这两句是为了默认的让所有控制器不支持屏幕旋转,个别控制器需要支持屏幕旋转的时候,再重写这两个方法。

注意:


#define IMAGEXY (ScreenWidth - 6) / 4.0
#define ScreenWidth [[UIScreen mainScreen] bounds].size.width
#define ScreenHeight [[UIScreen mainScreen] bounds].size.height
 
@implementation PublicDetailViewController
 
//在iOS7下这个必须加上这个,不然会崩溃,说preferredInterfaceOrientationForPresentation must return a supported interface orientation!
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}

//这个函数是说最佳的屏幕效果

-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation

在我们实际的应用开发的过程中,一般不会所有的控制器都支持屏幕旋转,一般是某几个页面需要支持,通常我们的做法是,在plist中选定我们需要支持的屏幕旋转方向;在根控制器中设置控制器不支持屏幕旋转的方向,在需要支持屏幕旋转的控制器中,重写方法,返回支持屏幕旋转的方向。

IOS系统支持屏幕旋转的方式,当屏幕的物理方向放生改变的时候,APP会去AppDeledate中调用application:supportedInterfaceOrientationsForWindow: 这个方法,如果重写了这个方法,将会使用这个方法的返回值,如果没有重写,这个方法会去读取Info.plist中的配置信息得到App支持的屏幕旋转方向;当一个ViewController将要被显示出来的时候,会默认显示当前设备的物理方向,当屏幕旋转的时候,会调用viewController中的- (NSUInteger)supportedInterfaceOrientations这个方法,这个方法会返回本ViewController支持的屏幕方向,如果这个方法返回的屏幕方向和APP支持的屏幕方向没有重合的,那么程序将会崩溃。如果有,则会显示为重合的屏幕方向。

你可能感兴趣的:(IOS开发 - 全局竖屏个别横屏的屏幕旋转问题)