I have a UIViewController
, which is presented modally (full screen) and I would like to disable autorotation in that view. I do not want to restrict it to landscape or portrait, just would like it to stay in whatever orientation it was originally presented.
我有一个UIViewController,它以模态方式呈现(全屏),我想在该视图中禁用自动旋转。我不想将它限制为横向或纵向,只是希望它保持在最初呈现的任何方向。
On iOS 6 it was sufficient to just override the method:
在iOS 6上,只需覆盖该方法就足够了:
- (BOOL)shouldAutorotate {
return NO;
}
And it did exactly what I wanted. On iOS 7 however, this seems to have no effect. The method does get called, but the return value seems to be ignored by the OS - it auto rotates no matter what.
它完全符合我的要求。然而,在iOS 7上,这似乎没有任何效果。该方法确实被调用,但操作系统似乎忽略了返回值 - 无论如何都会自动旋转。
The documentation does not mention any changes to this method. How can I achieve the desired effect on iOS 7?
文档未提及此方法的任何更改。如何在iOS 7上实现预期效果?
Edit: the view controller is being presented (not pushed!) by a UINavigationViewController
:
编辑:UINavigationViewController正在显示视图控制器(未推送!):
[self.navigationController presentViewController:vc animated:YES completion:nil];
Solution:
As odd as it may seem, but this solution was not published in the numerous existing questions on this topic. On iOS 7 it seems the answer the UINavigationController
gives to shouldAutorotate
is what the OS acts on. We need to subclass UINavigationController
to modify its behaviour.
虽然看似奇怪,但是这个解决方案并没有在关于这个主题的众多现有问题中发表。在iOS 7上,似乎UINavigationController给出的答案应该是操作系统所采用的操作。我们需要子类化UINavigationController来修改它的行为。
When dealing with a regular navigation stack it is indeed sufficient to just use [self.topViewController shouldAutorotate]
, but when there is modal view, it resides in self.presentedViewController
, not self.topViewController
. Thus the full solution looks like:
处理常规导航堆栈时,仅使用[self.topViewController shouldAutorotate]就足够了,但是当有模态视图时,它驻留在self.presentedViewController中,而不是self.topViewController。因此,完整的解决方案如下:
- (BOOL)shouldAutorotate {
UIViewController *vc;
if (self.presentedViewController) vc = self.presentedViewController;
else vc = [self topViewController];
return [vc shouldAutorotate];
}
2 个解决方案
#1
5
So I just tried you code and it worked which leads me to believe that you are presenting your UIViewController
in a UINavigationController
. For whatever reason, iOS 7 changed how UINavigationController
handle rotations.
所以我只是尝试了你的代码,它使我相信你在UINavigationController中展示你的UIViewController。无论出于何种原因,iOS 7改变了UINavigationController处理旋转的方式。
The easiest solution is to create a subclass of UINavigationController
that overrides the shouldAutorotate
method and returns the value from the topViewController.
最简单的解决方案是创建UINavigationController的子类,该子类重写shouldAutorotate方法并从topViewController返回值。
@interface CustomNavigationController : UINavigationController
@end
@implementation CustomNavigationController
- (BOOL)shouldAutorotate
{
return [[self topViewController] shouldAutorotate];
}
@end
So instead of doing this, where viewController
is your object that return NO
for shouldAutorotate
.
所以不要这样做,而viewController是你的对象,它为shouldAutorotate返回NO。
UINavigaitonController *navController = [UINavigationController alloc] initWithRootViewController:viewController];
[self presentViewController:navController animated:YES completion:nil];
You would use the CustomNavigationController instead
您将使用CustomNavigationController
CustomNavigationController *customNavController = [CustomNavigationController alloc] initWithRootViewController:viewController];
[self presentViewController:customNavController animated:YES completion:nil];
#2
-1
#import <objc/message.h>
-(void)viewDidAppear:(BOOL)animated{
objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait );
}
see How do I programmatically set device orientation in iOS7?
请参阅如何在iOS7中以编程方式设置设备方向?
But take the case you are using this method because it is a private API, and your app may be rejected by Apple. So, maybe is better to set orientation from Project details -> General -> Deployment Info tab, choose Landscape Left and Landscape Right choice only. This can be a better approach, if all your views need only one kind of orientation.
但请假设您使用此方法,因为它是私有API,Apple可能会拒绝您的应用。因此,最好从项目详细信息 - >常规 - >部署信息选项卡设置方向,仅选择横向左侧和右侧风景。如果您的所有视图只需要一种方向,这可能是一种更好的方法。
#1
5
So I just tried you code and it worked which leads me to believe that you are presenting your UIViewController
in a UINavigationController
. For whatever reason, iOS 7 changed how UINavigationController
handle rotations.
所以我只是尝试了你的代码,它使我相信你在UINavigationController中展示你的UIViewController。无论出于何种原因,iOS 7改变了UINavigationController处理旋转的方式。
The easiest solution is to create a subclass of UINavigationController
that overrides the shouldAutorotate
method and returns the value from the topViewController.
最简单的解决方案是创建UINavigationController的子类,该子类重写shouldAutorotate方法并从topViewController返回值。
@interface CustomNavigationController : UINavigationController
@end
@implementation CustomNavigationController
- (BOOL)shouldAutorotate
{
return [[self topViewController] shouldAutorotate];
}
@end
So instead of doing this, where viewController
is your object that return NO
for shouldAutorotate
.
所以不要这样做,而viewController是你的对象,它为shouldAutorotate返回NO。
UINavigaitonController *navController = [UINavigationController alloc] initWithRootViewController:viewController];
[self presentViewController:navController animated:YES completion:nil];
You would use the CustomNavigationController instead
您将使用CustomNavigationController
CustomNavigationController *customNavController = [CustomNavigationController alloc] initWithRootViewController:viewController];
[self presentViewController:customNavController animated:YES completion:nil];
#2
-1
#import <objc/message.h>
-(void)viewDidAppear:(BOOL)animated{
objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationPortrait );
}
see How do I programmatically set device orientation in iOS7?
请参阅如何在iOS7中以编程方式设置设备方向?
But take the case you are using this method because it is a private API, and your app may be rejected by Apple. So, maybe is better to set orientation from Project details -> General -> Deployment Info tab, choose Landscape Left and Landscape Right choice only. This can be a better approach, if all your views need only one kind of orientation.
但请假设您使用此方法,因为它是私有API,Apple可能会拒绝您的应用。因此,最好从项目详细信息 - >常规 - >部署信息选项卡设置方向,仅选择横向左侧和右侧风景。如果您的所有视图只需要一种方向,这可能是一种更好的方法。