iOS - 不同视图控制器的不同屏幕方向

时间:2014-07-06 14:42:36

标签: ios iphone objective-c uinavigationcontroller uiinterfaceorientation

我知道这里有很多问题和讨论,但我花了最近几天在互联网上搜索不同的解决方案,无论我尝试什么 - 似乎都没有用。

编辑: 试过this solution,仍然没有运气......

我有一个iOS7应用程序(我目前不关心对iOS6的支持,但它会很高兴)有一个根视图控制器,其菜单从侧面滑动({{ 3}},具体而言,让你在不同的屏幕之间切换。选定的屏幕被加载到导航控制器中,并且有一个"模态"在导航控制器和屏幕之间输入segue'视图控制器(首先出现的屏幕除外,它与根视图控制器有关系)。我也试过这个" push" segues,相同的结果。 其中一个屏幕必须仅以横向模式显示,其他屏幕仅以纵向显示。

为此目的,在我的根视图控制器中,我实现了以下内容:

- (void)awakeFromNib
{
    self.contentViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"contentController"];
    self.menuViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"menuController"];
}

-(NSUInteger)supportedInterfaceOrientations
{
    if (self.contentViewController)
        return [self.contentViewController supportedInterfaceOrientations];

    return UIInterfaceOrientationMaskPortrait;
}

-(BOOL)shouldAutorotate
{
    return YES;
}

在我的导航视图控制器中,我实现了以下内容:

-(BOOL)shouldAutorotate
{
    return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
    return [self.topViewController supportedInterfaceOrientations];
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [self.topViewController preferredInterfaceOrientationForPresentation];
}

并在每个肖像画面中'查看控制器我已实施:

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}

并在横向屏幕中:

- (NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscape;
}
-(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeLeft;
}

该应用的第一个屏幕是纵向屏幕。所以会发生什么,应用程序以纵向模式加载并且不会旋转到任何其他方向(这很棒)。但!加载横向屏幕后,它将以纵向模式加载,只有当我将设备旋转到横向模式时,它才会旋转并锁定为横向模式。一旦我切换回纵向屏幕,它将以横向模式加载,并且只有当我将设备旋转为纵向时,才会旋转并锁定为纵向模式,并且由于某种原因使得屏幕非常窄...

我最接近一个体面的解决方案是在横向屏幕的视图控制器中实现这一点:

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];
    CGAffineTransform landscapeTransform = CGAffineTransformMakeRotation(degreesToRadian(270));
    landscapeTransform = CGAffineTransformTranslate(landscapeTransform, 0.0, 0.0);
    [self.navigationController.view setTransform:landscapeTransform];
    self.navigationController.view.bounds = CGRectMake(0.0, 0.0, screenRect.size.height, screenRect.size.width);
}

-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
    CGAffineTransform landscapeTransform = CGAffineTransformMakeRotation(degreesToRadian(0));
    landscapeTransform = CGAffineTransformTranslate(landscapeTransform, 0.0, 0.0);
    [self.navigationController.view setTransform:landscapeTransform];
    self.navigationController.view.bounds = CGRectMake(0.0, 0.0, screenRect.size.width, screenRect.size.height);
}
#define degreesToRadian(x) (M_PI * (x)/180.0)

将此视图控制器的支持和首选方向更改为纵向。这基本上使整个应用程序锁定在纵向模式。 虽然它看起来很好,但它似乎有点粗略,我宁愿有一个"清洁"解决方案,左右支持景观。关于我在这里缺少什么的想法?

如果您需要我提供更多代码,请告诉我。 谢谢!! :)

1 个答案:

答案 0 :(得分:1)

好的,如果这对任何人都感兴趣,这是我的解决方案,使用接受的答案here

我缺少的是我的方法 - 景观VC不能与肖像VC一样在根VC下,它需要或拥有自己的根VC,这是风景。

首先,我将景观VC与故事板中的其余部分分开,现在它完全独立。接下来,我创建了一个"视图控制器开关"方法,它基本上加载一个新的控制器,将其设置为根控制器,并释放以前的根控制器:

+(void)loadController:(UIViewController *)VControllerToLoad andRelease:(UIViewController *)VControllerToRelease
{
    //adjust the frame of the new controller
    CGRect statusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
    CGRect windowFrame = [[UIScreen mainScreen] bounds];
    CGRect firstViewFrame = CGRectMake(statusBarFrame.origin.x, statusBarFrame.size.height, windowFrame.size.width, windowFrame.size.height - statusBarFrame.size.height);
    VControllerToLoad.view.frame = firstViewFrame;
    //set the new controller as the root controller
    [[[UIApplication sharedApplication].delegate window] setRootViewController:VControllerToLoad];
    //kill the previous view controller
    [VControllerToRelease.view removeFromSuperview];
}

在风景VC中,我添加了以下代码:

-(BOOL)shouldAutorotate
{
    return YES;
}

每当我需要呈现风景VC或返回人像VC时,我只使用VC切换方法。例如:

[AppUtils loadController:landscapeViewController andRelease:portraitNavigationController];

那就是它!现在一切都像魅力一样! :)