繁体   English   中英

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

[英]iOS - different screen orientations for different view controllers

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

编辑:尝试过这个解决方案 ,仍然没有运气......

我有一个iOS7应用程序(我目前不关心对iOS6的支持,但它会很高兴)有一个根视图控制器,其中有一个从侧面滑动的菜单( 这个是特定的)并让你在不同的屏幕之间切换。 选定的屏幕被加载到导航控制器中,导航控制器和屏幕的视图控制器之间存在“模态”类型segue(首先出现的屏幕除外,它与根视图控制器有关系)。 我也用“推”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)

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

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

好吧,万一这个人感兴趣,这是我的解决方案,采用公认的答案在这里

我缺少的是我的方法 - 景观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];

而已! 现在一切都像魅力一样! :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM