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

vra*_*urg 3 objective-c rotation orientation ios

所以,我有一个项目,我需要在用户按下按钮时强制更改方向.我在github上创建了一个示例应用程序来演示这个问题.

@interface DefaultViewController () {
    UIInterfaceOrientation _preferredOrientation;
}
Run Code Online (Sandbox Code Playgroud)

一些旋转处理位

- (BOOL)shouldAutorotate {
    return YES;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return _preferredOrientation;
}
Run Code Online (Sandbox Code Playgroud)

和切换

- (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];
}
Run Code Online (Sandbox Code Playgroud)

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

重现问题的步骤:

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

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

强迫方向改变问题

任何帮助将不胜感激!

Tom*_*man 5

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

[UIViewController attemptRotationToDeviceOrientation]; 
Run Code Online (Sandbox Code Playgroud)

很难确切说明为什么会这样.此调用要求尝试通过调用匹配interfaceOrientationto 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];
}
Run Code Online (Sandbox Code Playgroud)