如何在iOS 7中以编程方式设置设备方向?

Joh*_*art 71 xcode autorotate ios autolayout ios7

我正在使用AutoLayout在iPad应用程序上工作,如果用户启用某种模式("抬头"模式),我想只支持纵向(或纵向颠倒)方向,此外,如果设备在风景,我想自动切换到纵向模式.

在顶视图控制器中,我有以下内容:

- (NSUInteger) supportedInterfaceOrientations {
    if (self.modeHeadsUp) {
        return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
    } else {
        return UIInterfaceOrientationMaskAll;
    }
}

- (BOOL) shouldAutorotate {
    return TRUE;
}
Run Code Online (Sandbox Code Playgroud)

基于我在其他地方看到的答案,答案似乎是我应该使用"application setStatusBarOrientation".因此,在用户选择"抬头"模式的方法中,我包括:

    UIApplication *application = [UIApplication sharedApplication];
    [application setStatusBarOrientation:UIInterfaceOrientationPortrait
                                animated:YES];
Run Code Online (Sandbox Code Playgroud)

但是,这根本就没有做任何事情.虽然我可以物理移动设备以使其旋转为纵向,但它不会自动移动.

实际上,在运行上面的代码后尝试以横向模式尝试以编程方式设置方向时,当我使用以下代码查询应用程序"statusBarOrientation"时,它对于横向保持为"4":

UIApplication *application = [UIApplication sharedApplication];
int orientation = [application statusBarOrientation];
self.movesTextView.text = [NSString stringWithFormat:@"ORIENTATION %d", orientation];
Run Code Online (Sandbox Code Playgroud)

好像autolayout可能没有被setStatusBarOrientation触发,所以我试图在之后添加这个代码,没有效果:

    [super updateViewConstraints];
    [self.view updateConstraints];
Run Code Online (Sandbox Code Playgroud)

我意识到Apple希望将设备方向放在用户手中.但是,我希望能够在不进行"抬头"模式时支持横向模式.

我错过了能够强制改变方向的东西吗?

Sun*_*hah 190

对于iOS 7和8:

Objective-C的:

NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
Run Code Online (Sandbox Code Playgroud)

Swift 3+:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
Run Code Online (Sandbox Code Playgroud)

我打电话给它- viewDidAppear:.

  • 当我尝试这个时它只适用于iPad.iPad Mini(iOS 7.1)和iPhone 5s(iOS 7.1)都不起作用.适用于所有设备的模拟器 (4认同)
  • 有没有什么方法可以让这个工作*没有*动画? (4认同)
  • 这是黄金,特别是当您使用UIViewController.attemptRotationToDeviceOrientation()和http://stackoverflow.com/questions/24928057/xcode-only-one-view-landscape-mode时,您可以获得您想要的任何视图设置! (2认同)

Arp*_*xit 20

用这个.定位问题的完美解决方案..更早和更早

[[UIDevice currentDevice] setValue:
    [NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
        forKey:@"orientation"];
Run Code Online (Sandbox Code Playgroud)

  • 这已被 Apple_app review_ 团队接受(目前),但我不会说它“被 Apple 接受”。也就是说,这是一种使用键值编码的黑客行为,可能会在未来的任何 iOS 版本中停止工作。 (2认同)

sna*_*nak 10

当条件发生变化时,您需要调用attemptRotationToDeviceOrientation (UIViewController)系统调用supportedInterfaceOrientations.

  • 这仅在设备方向与 UIViewController 的方向不同时才有效 (2认同)

Rik*_*kco 6

NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
Run Code Online (Sandbox Code Playgroud)

确实可以,但是您必须在视图控制器中返回shouldAutorotate并使用YES

- (BOOL)shouldAutorotate
{
    return self.shouldAutoRotate;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果这样做,如果用户旋转设备,VC将自动旋转...因此我将其更改为:

@property (nonatomic, assign) BOOL shouldAutoRotate;

- (BOOL)shouldAutorotate
{
    return self.shouldAutoRotate;
}
Run Code Online (Sandbox Code Playgroud)

我打电话

- (void)swithInterfaceOrientation:(UIInterfaceOrientation)orientation
{
    self.rootVC.shouldAutoRotate = YES;

    NSNumber *value = [NSNumber numberWithInt: orientation];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}
Run Code Online (Sandbox Code Playgroud)

单击按钮以强制新的方向。要将shouldAutoRotate设置为NO,我将其添加到了rootVC

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    self.shouldAutoRotate = NO;
}
Run Code Online (Sandbox Code Playgroud)

PS:此替代方法也适用于所有模拟器。