iOS 6 旋转:supportedInterfaceOrientations 不起作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12410031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS 6 rotations: supportedInterfaceOrientations doesn′t work?
提问by stk
I′m having this issue with iOS 6 SDK: I′m having some views that should be allowed to rotate (e.g. a videoview), and some that don′t. Now I understand I have to check all orientations in the app′s Info.plist and then sort out in each ViewController, what should happen. But it doesn′t work! The app always rotates to the orientations, that are given in the Info.plist.
我在使用 iOS 6 SDK 时遇到了这个问题:我有一些应该允许旋转的视图(例如视频视图),而有些则不允许。现在我明白我必须检查应用程序的 Info.plist 中的所有方向,然后在每个 ViewController 中进行排序,应该会发生什么。但它不起作用!应用程序始终旋转到 Info.plist 中给出的方向。
Info.plist:
信息.plist:
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
any ViewController that shouldn′t be allowed to rotate:
任何不应允许旋转的 ViewController:
//deprecated
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
Observation: App rotates to landscape and portrait orientation. Any ideas why or what I′m doing wrong?
观察:应用程序旋转到横向和纵向。任何想法为什么或我做错了什么?
Cheers, Marc
干杯,马克
Edit: My latest findings also indicate, that if you want to have rotation at some point in your app, you haveto activate all four rotation directions in your project settings or Info.plist. An alternative to this is to override
编辑:我的最新发现还表明,如果您想在应用程序中的某个点进行旋转,则必须在项目设置或 Info.plist 中激活所有四个旋转方向。对此的替代方法是覆盖
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
in your AppDelegate, which overrides the Info.plist. It isn′t possible anymore to set only Portrait in your Info.plist and then having rotation in some ViewController by overriding shouldAutorotateToInterfaceOrientation or supportedInterfaceOrientations.
在您的 AppDelegate 中,它会覆盖 Info.plist。不再可能在 Info.plist 中只设置 Portrait,然后通过覆盖 shouldAutorotateToInterfaceOrientation 或 supportedInterfaceOrientations 在某些 ViewController 中进行旋转。
采纳答案by CSmith
If your ViewController is a child of a UINavigationController or UITabBarController, then it is the parent that is your problem. You might need to subclass that parent view controller, just overriding those InterfaceOrientation methods as you've shown in your question
如果您的 ViewController 是 UINavigationController 或 UITabBarController 的子级,那么父级就是您的问题。您可能需要对该父视图控制器进行子类化,只需覆盖您在问题中显示的那些 InterfaceOrientation 方法
EDIT:
编辑:
Example for portrait only TabBarController
仅纵向 TabBarController 的示例
@interface MyTabBarController : UITabBarController
{
}
@end
@implementation MyTabBarController
// put your shouldAutorotateToInterfaceOrientation and other overrides here
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
@end
回答by Evan Schoenberg
Adding to CSmith's answer above, the following code in a UINavigationController subclass allows delegation to the top view controller in the way that I expected this to work in the first place:
添加到上面 CSmith 的答案中,UINavigationController 子类中的以下代码允许以我最初期望的方式委托给顶视图控制器:
- (BOOL)shouldAutorotate;
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
if ([[self topViewController] respondsToSelector:@selector(supportedInterfaceOrientations)])
return [[self topViewController] supportedInterfaceOrientations];
else
return [super supportedInterfaceOrientations];
}
回答by Glenn Schmidt
Here's another alternative to CSmith's approach.
这是 CSmith 方法的另一种替代方法。
If you want to replicate the pre-iOS 6 behaviour where all the views in the navigation stack / tab bar have to agree on an allowable set of orientations, put this in your subclass of UITabBarController
or UINavigationController
:
如果您想复制 iOS 6 之前的行为,其中导航堆栈/选项卡栏中的所有视图都必须就一组允许的方向达成一致,请将其放在UITabBarController
or的子类中UINavigationController
:
- (NSUInteger)supportedInterfaceOrientations
{
NSUInteger orientations = [super supportedInterfaceOrientations];
for (UIViewController *controller in self.viewControllers)
orientations = orientations & [controller supportedInterfaceOrientations];
return orientations;
}
回答by Shimanski Artem
Try to add this category:
尝试添加此类别:
@interface UINavigationController(InterfaceOrientation)
@end
@implementation UINavigationController(InterfaceOrientation)
- (NSUInteger) supportedInterfaceOrientations {
if (self.viewControllers.count > 0)
return [[self.viewControllers objectAtIndex:0] supportedInterfaceOrientations];
else
return UIInterfaceOrientationMaskAll;
}
@end
回答by Alvivi
For people using UINavigationController and Swift, you can add this extension to your project. After that, navigation controllers delegate the control to their child controller.
对于使用的UINavigationController和斯威夫特的人,你可以将此扩展添加到您的项目。之后,导航控制器将控制委托给他们的子控制器。
extension UINavigationController {
override public func supportedInterfaceOrientations()
-> UIInterfaceOrientationMask {
if let ctrl = topViewController {
return ctrl.supportedInterfaceOrientations()
}
return super.supportedInterfaceOrientations()
}
override public func shouldAutorotate() -> Bool {
if let ctrl = topViewController {
return ctrl.shouldAutorotate()
}
return super.shouldAutorotate()
}
}
回答by Harikrishna Pai
@Alvivi's answer updated for Swift 4.
@Alvivi 为Swift 4更新了答案。
extension UINavigationController {
// Look for the supportedInterfaceOrientations of the topViewController
// Otherwise, viewController will rotate irrespective of the value returned by the ViewController
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if let ctrl = self.topViewController {
return ctrl.supportedInterfaceOrientations
}
return super.supportedInterfaceOrientations
}
// Look for the shouldAutorotate of the topViewController
// Otherwise, viewController will rotate irrespective of the value returned by the ViewController
override open var shouldAutorotate: Bool {
if let ctrl = self.topViewController {
return ctrl.shouldAutorotate
}
return super.shouldAutorotate
}
}
回答by SwiftArchitect
Further addition to @CSmith and @EvanSchoenberg.
对@CSmith 和@EvanSchoenberg 的进一步补充。
If you have some views that rotate, and some views that don't, you must create a custom instance of the UITabBarController
, yet still let each UIViewController
decide.
如果您有一些视图旋转,而一些视图没有旋转,则必须创建 的自定义实例UITabBarController
,但仍让每个视图自行UIViewController
决定。
- (BOOL)shouldAutorotate;
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
UIViewController * top;
UIViewController * tab = self.selectedViewController;
if([tab isKindOfClass:
([UINavigationController class])]) {
top = [((UINavigationController *)tab)
topViewController];
}
if ([top respondsToSelector:@selector(supportedInterfaceOrientations)])
return [top supportedInterfaceOrientations];
else
return [super supportedInterfaceOrientations];
}
回答by Jaroslav
@Shimanski Artem's answer is good, but I think using the topmost (currently visible) controller is better solution:
@Shimanski Artem 的回答很好,但我认为使用最顶层(当前可见)的控制器是更好的解决方案:
@interface UINavigationController(InterfaceOrientation)
@end
@implementation UINavigationController(InterfaceOrientation)
- (NSUInteger) supportedInterfaceOrientations {
if (self.viewControllers.count > 0){
return [[self.viewControllers objectAtIndex:[self.viewControllers count] - 1] supportedInterfaceOrientations];
}
return UIInterfaceOrientationMaskAll;
}
@end
回答by dana_a
As an alternate option, in case you want to preserve pre-iOS6 rotation functionality in your app:
作为替代选项,如果您想在您的应用中保留 iOS6 之前的旋转功能:
Here's a helpful bit of code on github that swizzles the method calls for iOS6 so that rotation works like it did on iOS4/iOS4. This really helped me, as I'm supporting a legacy app that really micro-manages its rotations. It would have been a lot of work to implement the changes required for iOS6. Kudos to the user who posted it.
这是github上的一些有用的代码,它混合了iOS6的方法调用,以便旋转像在iOS4/iOS4上一样工作。这真的对我有帮助,因为我正在支持一个真正微观管理其轮换的遗留应用程序。实现 iOS6 所需的更改需要做很多工作。感谢发布它的用户。