当supportedInterfaceOrientations 改变时如何通知系统?
Posted
技术标签:
【中文标题】当supportedInterfaceOrientations 改变时如何通知系统?【英文标题】:How do I notify system when supportedInterfaceOrientations changes? 【发布时间】:2012-10-31 01:47:26 【问题描述】:我的根视图控制器对supportedInterfaceOrientations
的实现几乎总是返回UIInterfaceOrientationMaskAll
,但是有一种极端情况会返回UIInterfaceOrientationMaskLandscape
。
如果用户旋转设备,这是可行的。但是,如果设备正处于纵向模式,则不会调用 supportedInterfaceOrientations
方法,除非用户手动旋转设备。
如何以编程方式告诉系统此方法的返回值已更改?
根据文档,我似乎应该能够调用 [UIViewController attemptRotationToDeviceOrientation]
但这没有任何效果(supportedInterfaceOrientations
永远不会被调用并且屏幕不会旋转)。
我发现了其他人发布的各种解决方法来尝试解决这个问题,但在我的测试中它们都不起作用。我怀疑他们可能在 ios 5.0 中工作过,但在 iOS 6.0 中没有。
我在根视图控制器的shouldAutorotate
方法中返回YES
。
【问题讨论】:
你解决过这个问题吗?我最近在 iOS7 中问了一个类似的问题:***.com/questions/20987249/… 【参考方案1】:首先,如果你想在横向模式下展示你的 UIViewController,它可能会很有用。
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
return UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight;
另外,很大程度上取决于您的 UIViewController 嵌入到哪个控制器中。
例如,如果它在 UINavigationController 内部,那么您可能需要将该 UINavigationController 子类化以覆盖这样的方向方法。
子类 UINavigationController(层次结构的顶部视图控制器将控制方向。)需要将其设置为 self.window.rootViewController。
- (BOOL)shouldAutorotate
return self.topViewController.shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations
return self.topViewController.supportedInterfaceOrientations;
从 iOS 6 开始,UINavigationController 不会向其 UIVIewControllers 请求方向支持。因此我们需要对它进行子类化。
注意:
每当 Push 操作完成时,总是会为 UINavigationController 调用 shouldAutorotate
和 supportedInterfaceOrientations
方法。
【讨论】:
我的视图层次结构很复杂。根控制器是一个标签栏控制器,它转发到活动标签上。活动选项卡视图控制器包含一个导航控制器(除其他外),除了可以推送到导航控制器的控制器之外的所有控制器都可以在任何方向上工作。它们都是子类并返回正确的方向设置,我通过断点确认,当我的横向视图被推送时,它确实返回UIInterfaceOrientationMaskLandscape
并且该值由根视图控制器返回,但它不会旋转;它保持纵向。
如果用户旋转到横向,它会切换到横向并且不会回到纵向。但是当视图被推送时,即使它只返回横向,它仍然保持纵向直到被手动旋转。此特定视图用于用手指绘制签名,并且由于使用签名的位置的业务逻辑(上传到远程服务器之后),它确实需要横向。我的客户非常恼火,因为它在 iOS 5 中工作,但现在在 iOS 6 中却没有,尽管进行了大量调试。 >:(
您是否尝试将您的UINavigationController
子类化?我之前也遇到过类似的问题,用这个方法解决了。
实际上发生的情况是,在 iOS UIViewController 都有权自行旋转并支持所需的方向。但是,在 iOS 6 中,UIViewController
必须请求其子类的许可,例如。 UINavigationController
或 UITabbarController
是的,导航控制器是子类,并且返回横向,因为它是唯一支持的方向(当特定视图被推送时)。【参考方案2】:
引用自 Apple 的 UIViewController 类参考:
注意:在启动时,应用程序应始终将其界面设置为纵向。在 application:didFinishLaunchingWithOptions: 方法返回后,应用程序使用上述视图控制器旋转机制在显示窗口之前将视图旋转到适当的方向。
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
如果界面以纵向开始,则即使用户在设备侧放的情况下打开应用程序,自动旋转也应该能够处理调整。
更新:我发现这篇文章应该有助于发布后的轮换。显然,iOS 6 会查看导航控制器以确定支持的设备方向。
How to force a UIViewController to Portrait orientation in iOS 6
【讨论】:
我不是在谈论启动时,我是在谈论当用户在其中一个视图中点击一个按钮时,它会将您带到应用程序中无法纵向使用的区域.一个视图控制器的界面只能用于 16:9 的纵横比。 9:16 是完全不能接受的。 我误解了你的问题。请参阅我的更新答案。希望对您有所帮助! 我都做了,还是不行。我有一个导航控制器,以纵向模式显示视图控制器。你点击一个按钮,它会推动一个不能在纵向模式下使用的新视图控制器。在 iOS 5 上,它将旋转为横向。在 iOS 6 上,即使视图控制器在相关方法中都返回“仅横向”,它也会以纵向模式显示。如果用户将手机旋转到横向,它会切换到横向并且不能改回纵向,所以它可以工作。我希望它在视图被推送时切换到横向,这就是它在 iOS 5 中所做的【参考方案3】:您需要手动旋转它。您需要在视图控制器的 viewWillAppear:
方法中调用以下逻辑:
UIDeviceOrientation curDevOrientation = [[UIDevice currentDevice] orientation];
if (![self supportsOrientation:curDevOrientation])
// We're going to rotate 90 degrees clockwise. First figure out what that
// means to the status bar.
UIInterfaceOrientation newStatusBarOrientation;
switch (curDevOrientation)
case UIDeviceOrientationPortrait:
newStatusBarOrientation = UIInterfaceOrientationLandscapeRight;
break;
case UIDeviceOrientationPortraitUpsideDown:
newStatusBarOrientation = UIInterfaceOrientationLandscapeLeft;
break;
[[UIApplication sharedApplication] setStatusBarOrientation:newStatusBarOrientation animated:NO];
// Now rotate the view 90 degrees clockwise.
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI * 90.0 / 180.0);
self.view.transform = transform;
这应该旋转特定视图控制器的视图,无论何时出现。
【讨论】:
以上是关于当supportedInterfaceOrientations 改变时如何通知系统?的主要内容,如果未能解决你的问题,请参考以下文章