【问题标题】:UINavigationController Force RotateUINavigationController 强制旋转
【发布时间】:2012-04-07 06:55:00
【问题描述】:

我的应用程序主要是纵向的,但是有一个视图需要横向。

我的视图包含在 UINavigationController 中,这(显然)是导致此问题的原因。

除了一个之外的所有 UIViewControllers 都有这个:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

需要 Landscape 的 UIViewController 有这个:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}

现在,当用户到达横向 UIViewController 时,它会以纵向显示。然后,用户可以旋转他们的手机,它会按照我的意愿横向显示(锁定为横向)。然后用户继续使用纵向 UIViewController,同样的情况发生:它从横向开始,然后他们旋转手机,它再次变成纵向(并锁定为纵向)。

UIViewController 之间似乎允许方向锁定,但是自动旋转/以编程方式更改方向被某种方式阻止了。

如何强制手机更新到正确的方向?

有一个临时解决方案:我可以检测设备的方向并显示一条消息,要求他们在不正确时旋转设备,但这不是最佳选择。

【问题讨论】:

    标签: iphone objective-c ios ios5 uinavigationcontroller


    【解决方案1】:

    使用这个,

    [[UIDevice currentDevice]performSelector:@selector(setOrientation:) withObject:(__bridge id)((void *)UIInterfaceOrientationLandscapeRight)];
    

    【讨论】:

    • 工作,但我觉得它可能会在未来打破,因为它可能没有记录
    • 不,这是苹果原生的方向。我已经使用了这个并获得了苹果的批准用于我的 2 个应用程序。
    • 更好的写法:[[UIDevice currentDevice] setValue:@(UIDeviceOrientationLandscapeLeft) forKey:@"orientation"]
    【解决方案2】:

    我的一个应用程序也有同样的要求!!!

    幸运的是我找到了解决方案!

    为了保持主视图控制器的横向,无论从哪个方向弹出/推送,我都做了以下事情:(在 viewWillAppear 中:)

    //set statusbar to the desired rotation position
    [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];
    
    //present/dismiss viewcontroller in order to activate rotating.
    UIViewController *mVC = [[[UIViewController alloc] init] autorelease];
    [self presentModalViewController:mVC animated:NO];
    [self dismissModalViewControllerAnimated:NO];
    

    P.S.在 sdk 3.2.5 ios 5.0.1 上测试。

    附:在 iOS 8 上,先前的答案导致一些屏幕闪烁,而且 - 它不稳定(在某些情况下它不再适合我了。)所以,为了我的需要,我将代码更改为:(ARC)

    //set statusbar to the desired rotation position
    [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO];
    
    [self.navigationController presentViewController:[UIViewController new] animated:NO completion:^{
        dispatch_after(0, dispatch_get_main_queue(), ^{
            [self.navigationController dismissViewControllerAnimated:NO completion:nil];
        });
    }];
    
    //I added this code in viewDidDissapear on viewController class, which will be popped back.
    

    希望它会有所帮助!

    【讨论】:

    • 适用于 iOS6beta1。谢谢!
    • 对我来说,使用UINavigationController,这种方法失败了,因为虽然状态栏会旋转,但界面仍然存在。所以用户必须再次旋转它来设置界面。
    • 是的,我自己也遇到过这种技巧根本行不通的情况。这意味着,您的应用程序的功能(元素自动调整大小或太深的视图/子视图集成或其他可能的东西)不允许此功能工作。对不起。在简单的情况下,它会有所帮助。
    • 在viewcontroller中,需要特定的旋转。
    • 我在 iOS8 上遇到了同样的问题(闪烁)。在我的情况下,我需要在子视图转换期间更改设备旋转。为了减少这种闪光效果,我已将呈现视图的背景颜色更改为白色。
    【解决方案3】:

    这可能会有所帮助。您可以在出现时根据需要调用以下方法。例如在-viewWillAppear:animated

    尝试RotationToDeviceOrientation 尝试将所有窗口旋转到设备的方向。

    + (void)attemptRotationToDeviceOrientation
    

    讨论

    一些视图控制器可能希望使用特定于应用程序的条件 确定他们执行的返回值 shouldAutorotateToInterfaceOrientation:方法。如果你的看法 控制器会这样做,当这些条件发生变化时,您的应用程序应该 调用这个类方法。系统立即尝试旋转到 新的方向。只要每个相关视图都会发生轮换 控制器在其实现中返回 YES shouldAutorotateToInterfaceOrientation: 方法。

    可用性

    适用于 iOS 5.0 及更高版本。 http://developer.apple.com/library/ios/#DOCUMENTATION/UIKit/Reference/UIViewController_Class/Reference/Reference.html

    【讨论】:

    • 哇+1 好技巧(以及 os5 中的另一个好东西)。这个问题让我头疼了好几个小时。
    • 那里有各种各样的函数来设置自动旋转设置,但它们似乎并没有被一致地调用。我把 -(BOOL) shouldAutorotate { return NO; } 但这从未被调用过。
    • 太棒了——太好了!这让我多年来一直想不通!非常感谢
    猜你喜欢
    • 2013-02-14
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 2015-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多