iOS:在旋转iphone后,从仅支持纵向模式的视图控制器直接呈现横向视图控制器

时间:2012-10-21 21:40:45

标签: iphone ios uiviewcontroller

我有一个应用程序始终以纵向模式呈现(在Xcode项目的摘要中,仅支持纵向)。

现在我想要做的是当我使用应用程序时,从应用程序的任何视图控制器,如果我在横向右侧旋转设备,应用程序在横向右侧呈现视图控制器(ARViewController.m),事实上,向右侧的旋转是呈现ARViewController.m的触发器。但我所经历的是,因为第一个视图控制器只支持肖像,即使我将设备定位在横向右侧,我想从第一个视图控制器(ARViewController.m)呈现的视图控制器(ARViewController.m)也是纵向的,不是在风景中。

即使我在第二个视图控制器(ARViewController.m)中写入它,它也不会自动旋转(此视图控制器可以在每个方向显示):

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ 
  return YES;
}

在第二个视图控制器(ARViewController.m)出现后,我必须旋转一次iphone。

以下是我从第一个视图控制器调用第二个视图控制器(ARViewController.m)的方法:

ARViewController *arVC = [[ARViewController alloc] initWithNibName:@"ARViewController" bundle:nil];
[self presentModalViewController:arVC animated:YES];

我从“ViewController.m”调用它,这个被定义为AppDelegate.m中的rootViewController

这是我第一次做这些事情,我一直在寻找解决方案,但仍然存在同样的问题。关于这个的任何提示?

2 个答案:

答案 0 :(得分:5)

我终于解决了这个问题,我想有其他选择,但这个问题很好:

事实上,我只保留了纵向限制。然后当我向右或向左转动手机时,我会以模态方式调用我的AR​​ViewController,但在加载之前,我强制将此视图控制器设置为横向(在viewWillAppear中),方法如下所示:

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

-(void) transformView2ToLandscape {

NSInteger rotationDirection;
UIDeviceOrientation currentOrientation = [[UIDevice currentDevice] orientation];

if(currentOrientation == UIDeviceOrientationLandscapeLeft){
    rotationDirection = 1;
}else {
    rotationDirection = -1;
}

CGAffineTransform transform = [arController.viewController.view transform];
transform = CGAffineTransformRotate(transform, degreesToRadians(rotationDirection * 90));
[arController.viewController.view setTransform: transform];}

编辑:在Swift 4中

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    transformViewToLansdcape()
}

func transformViewToLansdcape(){
    var rotationDir : Int
    if(UIDeviceOrientationIsLandscape(UIDevice.current.orientation)){
        rotationDir = 1
    }else{
        rotationDir = -1
    }
    var transform = self.view.transform
    //90 for landscapeLeft and 270 for landscapeRight
    transform = transform.rotated(by: (rotationDir*270).degreesToRadians)
    self.view.transform = transform
}

extension BinaryInteger {
    var degreesToRadians: CGFloat {
        return CGFloat(Int(self)) * .pi / 180
    }
}

答案 1 :(得分:0)

我发现,首先,停止整个应用程序轮换的是项目摘要表。您应该做的是取消选择项目摘要表中的限制。只需在每个UIViewController中添加一个方法,就像你喜欢它一样。在您拥有的UIViewController中,使该方法可用于横向方向和方法。实施方法

[UIViewControllerSubclass willRotateToInterfaceOrientation:<interfaceOrientation> duration:<NSTimeInterval>]

苹果说:

willRotateToInterfaceOrientation:持续时间:

在用户界面开始旋转之前发送到视图控制器。

  • (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

<强>参数

toInterfaceOrientation

用户界面的新方向。可能的值描述于 UIInterfaceOrientation。

持续时间

待定轮换的持续时间,以秒为单位。

<强>讨论

子类可以覆盖此方法以在旋转之前立即执行其他操作。例如,您可以使用此方法禁用视图交互,停止媒体播放或暂时关闭昂贵的绘图或实时更新。您也可以使用它来交换当前视图,以反映新的界面方向。调用此方法时,interfaceOrientation属性仍包含视图的原始方向。

无论您的代码是执行一步还是两步旋转,都会调用此方法。


所以,这看起来像你正在寻找的方法。只需实现这一点,并将您的视图调用代码放入&amp;它应该工作。 (另外,将其中一个放在所呈现的视图中,以便在向后旋转时返回)

另外,你应该考虑不要以模态方式呈现视图控制器,因为它正在旋转,很明显显示器正在改变。