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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在iOS 7中以编程方式设置设备方向?相关的知识,希望对你有一定的参考价值。

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

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

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

- (BOOL) shouldAutorotate {
    return TRUE;
}

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

    UIApplication *application = [UIApplication sharedApplication];
    [application setStatusBarOrientation:UIInterfaceOrientationPortrait
                                animated:YES];

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

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

UIApplication *application = [UIApplication sharedApplication];
int orientation = [application statusBarOrientation];
self.movesTextView.text = [NSString stringWithFormat:@"ORIENTATION %d", orientation];

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

    [super updateViewConstraints];
    [self.view updateConstraints];

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

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

答案

对于ios 7和8:

Objective-C的:

NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];

Swift 3+:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")

我在- viewDidAppear:称呼它。

另一答案

如果你有一个应该保持在纵向模式的UIViewController,只需添加这个覆盖就可以了。

override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
    return UIInterfaceOrientationMask.Portrait
}

最好的部分是在显示此视图时没有动画,它刚刚处于正确的方向。

另一答案

基础UINavigationController应具有以下回调,以便子项可以决定他们想要的方向。

-(NSUInteger)supportedInterfaceOrientations {
    UIViewController *topVC = self.topViewController;
    return topVC.supportedInterfaceOrientations;
}

-(BOOL)shouldAutorotate {
   UIViewController *topVC = self.topViewController;
   return [topVC shouldAutorotate];
}
另一答案

如果您只想要纵向模式,在iOS 9(Xcode 7)中,您可以:

  • 转到Info.plist
  • 选择“支持的界面方向”项
  • 删除“横向(左主页按钮)”和“横向(右主页按钮)”

enter image description here

另一答案

我遇到的问题与你类似。我需要锁定某些屏幕的设备方向(如Login)并允许其他屏幕旋转。

经过一些更改并在下面得到一些答案后,我通过以下方式完成了

  • 在项目的Info.plist中启用所有方向。

enter image description here

  • 在我需要设备不旋转的那些ViewControllers中禁用方向,就像在我的情况下的登录屏幕中一样。我需要在这个VC中覆盖shouldAutorotate方法:

-(BOOL)shouldAutorotate{ return NO; }

希望这对你有用。

另一答案

这是iOS 7,8,9,10的完整工作示例如何将应用方向更改为当前相反的方向

Objective-C的

- (void)flipOrientation
{
    NSNumber *value;
    UIInterfaceOrientation currentOrientation = [[UIApplication sharedApplication] statusBarOrientation];
    if(UIInterfaceOrientationIsPortrait(currentOrientation))
    {
        if(currentOrientation == UIInterfaceOrientationPortrait)
        {
            value = [NSNumber numberWithInt:UIInterfaceOrientationPortraitUpsideDown];
        }
        else //if(currentOrientation == UIInterfaceOrientationPortraitUpsideDown)
        {
            value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
        }
    }
    else
    {
        if(currentOrientation == UIInterfaceOrientationLandscapeRight)
        {
            value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
        }
        else //if(currentOrientation == UIInterfaceOrientationLandscapeLeft)
        {
            value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight];
        }
    }
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    [UIViewController attemptRotationToDeviceOrientation];
}

斯威夫特3

func flipOrientation() -> Void
{
    let currentOrientation : UIInterfaceOrientation = UIApplication.shared.statusBarOrientation
    var value : Int = 0;
    if(UIInterfaceOrientationIsPortrait(currentOrientation))
    {
        if(currentOrientation == UIInterfaceOrientation.portrait)
        {
            value = UIInterfaceOrientation.portraitUpsideDown.rawValue
        }
        else //if(currentOrientation == UIInterfaceOrientation.portraitUpsideDown)
        {
            value = UIInterfaceOrientation.portrait.rawValue
        }
    }
    else
    {
        if(currentOrientation == UIInterfaceOrientation.landscapeRight)
        {
            value = UIInterfaceOrientation.landscapeLeft.rawValue
        }
        else //if(currentOrientation == UIInterfaceOrientation.landscapeLeft)
        {
            value = UIInterfaceOrientation.landscapeRight.rawValue
        }
    }
    UIDevice.current.setValue(value, forKey: "orientation")
    UIViewController.attemptRotationToDeviceOrientation()
}
另一答案

请尝试使用您的代码。

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation  

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

一旦用户选择任何选项,然后调用此方法,因为用户可以处于横向模式,然后他可以在同一个视图控制器中只设置纵向模式,因此自动视图应该移动到纵向模式,以便在该按钮中调用此方法

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
另一答案

这对我很有帮助....

NSNumber *value = [NSNumber numberWithInt:UIDeviceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"];
另一答案

对于像我这样努力获得@Sunny Shah的人来说,接受了在iPad上工作的答案。您需要在项目设置中设置“需要全屏”复选框。请注意,这会阻止您的应用在多任务模式下工作,这可能是可接受的,也可能是不可接受的。

enter image description here

另一答案

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

[[UIDevice currentDevice] setValue:
    [NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
        forKey:@"orientation"];
另一答案

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

另一答案

这适用于Xcode 6和5。

- (BOOL)shouldAutorotate {
    return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
    return (UIInterfaceOrientationMaskPortrait);
}
另一答案
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"];

确实有效但您必须在视图控制器中返回shouldAutorotate并带YES

- (BOOL)shouldAutorotate
{
    return self.shouldAutoRotate;
}

但是如果你这样做,你的VC会在用户旋转设备时自动旋转...所以我把它改为:

@property (nonatomic, assign) BOOL shouldAutoRotate;

- (BOOL)shouldAutorotate
{
    return self.shouldAutoRotate;
}

我打电话给

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

    NSNumber *value = [NSNumber numberWithInt: orientation];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
}

通过按钮单击强制新方向。要将shouldAutoRotate设置为NO,我将添加到rootVC中

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    self.shouldAutoRotate = NO;
}

PS:此解决方法也适用于所有模拟器。

另一答案

对我有用的唯一方法是呈现虚拟模态视图控制器。

UIViewController* dummyVC = [[UIViewController alloc] init];
dummyVC.view = [[UIView alloc] init];
[self presentModalViewController:dummyVC animated:NO];
[self dismissModalViewControllerAnimated:NO];

当取消模态视图控制器时,将要求VC更新接口方向。

奇怪的是,当推送/弹出具有不同支持的接口方向的子视图控制器时,UINavigationController正是这样做的(在iOS 6.1,7.0上测试)。