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

3

我知道这个问题在这里已经被问过和讨论过很多次,但是我花了最近几天的时间搜寻不同的解决方案,无论我尝试什么 - 似乎都没有用。

编辑: 也尝试了这个解决方案,仍然没有成功...

我有一个iOS7应用程序(我目前不关心对iOS6的支持,但有这个支持会很好),它有一个根视图控制器,带有从侧面滑出的菜单(这个,具体来说),并允许您在不同的屏幕之间切换。所选屏幕加载到导航控制器中,并且在导航控制器和屏幕的视图控制器之间有“模态”类型的转场(除了首先出现的屏幕与根视图控制器有关系)。我还尝试过使用“推送”转场,结果相同。 其中一个屏幕必须仅以横向模式显示,其他屏幕必须仅以纵向模式显示。

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

- (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个回答

1

好的,以防这个内容对任何人有兴趣,这是我的解决方案,使用了被接受的答案这里

我缺少的是在我的方法中 - 横向VC不能与纵向VC位于同一个根VC下,它需要是或拥有自己的根VC,它处于横向。

因此,首先,我在storyboard中将横向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;
}

每当我需要呈现横屏视图控制器或者返回竖屏视图控制器时,我只需使用视图控制器切换方法。例如:

[AppUtils loadController:landscapeViewController andRelease:portraitNavigationController];

那就这样!现在一切都像魔法般运作! :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接