程序化界面方向更改不适用于iOS

时间:2014-01-13 20:45:58

标签: ios objective-c rotation orientation

所以,我有一个项目,我需要在用户按下按钮时强制更改方向。我创建了一个sample app on github来证明这个问题。

@interface DefaultViewController () {
    UIInterfaceOrientation _preferredOrientation;
}

一些旋转处理位

- (BOOL)shouldAutorotate {
    return YES;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return _preferredOrientation;
}

和切换

- (IBAction)toggleButtonPressed:(id)sender {
    _preferredOrientation = UIInterfaceOrientationIsPortrait(_preferredOrientation)
        ? UIInterfaceOrientationLandscapeRight
        : UIInterfaceOrientationPortrait;

    [self forceOrientationChange];
}


- (void)forceOrientationChange
{
    UIViewController *vc = [[UIViewController alloc] init];
    [self presentViewController:vc animated:NO completion:nil];

    [UIView animateWithDuration:.3 animations:^{
        [vc dismissViewControllerAnimated:NO completion:nil];
    } completion:nil];
}

所以,当您按下切换按钮时,这似乎工作正常,它会按预期更改方向。但是当我开始改变设备的实际方向时,就会出现问题。

重现问题的步骤:

  1. 纵向打开应用
  2. 按此按钮强制方向更改为横向(保持实际设备的纵向)
  3. 再次按此按钮可强制旋转回到纵向(仍保持设备的纵向)
  4. 无需按下按钮
  5. 即可将实际设备旋转至横向

    结果是视图不会旋转到横向,但状态栏会旋转。

    Forced orientation change issue

    非常感谢任何帮助!

3 个答案:

答案 0 :(得分:5)

我能够通过在呈现和解除视图控制器之前添加以下行来解决此问题:

[UIViewController attemptRotationToDeviceOrientation]; 

很难确切说明为什么会这样。如果返回interfaceOrientation,此调用会通过调用deviceOrientation以及后续轮播方法要求尝试将shouldAutorotateToInterfaceOrientation:YES匹配。

由于无论设备方向如何强制接口方向所需的解决方法,接口和设备方向似乎都会失去同步。在我看来,仍然不应该发生,因为解决方法仍然是提供的方法的合法使用。它可能是Apple的旋转/定位堆栈中的一个错误。

完整方法:

- (void)forceOrientationChange
{
    UIViewController *vc = [[UIViewController alloc] init];

    [UIViewController attemptRotationToDeviceOrientation]; /* Add this line */

    [self presentViewController:vc animated:NO completion:nil];

    [UIView animateWithDuration:.3 animations:^{
        [vc dismissViewControllerAnimated:NO completion:nil];
    } completion:nil];
}

答案 1 :(得分:1)

当我们谈论方向时,它们是图中的两件事:

设备方向 界面定位 仅通过名称清楚,设备方向告诉设备的方向,界面方向说明您的应用在哪个方向呈现其界面。

您正在做的是,您的应用支持所有方向。您必须在项目中检查标记所有方向。

现在,当您将设备的方向从纵向更改为横向时,如果已将interfaceOrientation设置为以编程方式处于纵向模式,则会发生这种情况。随着设备方向的改变,状态栏的方向也会发生变化。但是,由于您将应用程序的界面限制为纵向,因此不会改变其方向。

所以你可以这样做:

  1. 取消选中您应用的横向支持&检查问题是否仍然存在。
  2. 让我知道你在第一步后发生了什么:)

答案 2 :(得分:0)

使用此代码:

UIApplication *application = [UIApplication sharedApplication];
[application setStatusBarOrientation:UIDeviceOrientationLandscapeLeft 
                            animated:YES];
[[UIDevice currentDevice] setOrientation:UIDeviceOrientationLandscapeLeft];
[super updateViewConstraints];
[self.view updateConstraints];