2013-10-21 98 views
9

我读过很多关于SO的答案,但我似乎无法在iOS7上使用自动旋转。在iOS7中处理一个视图控制器的自动旋转

我只需要一个视图控制器旋转,所以我不希望在我的Info.plist设置旋转设置。

据我了解苹果的文档,单一视图控制器可以通过简单地重写两种方法覆盖全局的旋转设置(从Info.plist中)。 Info.plist中设置为仅允许肖像,和我的视图控制器实现下列方法:

- (NSUInteger)supportedInterfaceOrientations 
{ 
    NSLog(@"%s", __PRETTY_FUNCTION__); 
    return UIInterfaceOrientationMaskAllButUpsideDown; 
} 

- (BOOL)shouldAutorotate 
{ 
    NSLog(@"%s", __PRETTY_FUNCTION__); 
    return true; 
} 

我看到在旋转这些语句的NSLog,但没有旋转。

如果我使用正确的旋转设置Info.plist中,我的看法会旋转,但如果我试图依靠我的视图控制器上。

不知道它的问题,但我想旋转视图是从使用自动布局的.xib。

另外,我的视图控制器被模态呈现,并且包含在导航控制器。我试过只是自己呈现视图控制器,并且不起作用。我也尝试adding a category to UINavigationController从它的topViewController获取它的自动旋转方向。

+0

同样的问题;另外,我想让我的应用程序兼容iOS5,所以我不能使用supportedInterfaceOrientations。我正在使用其他两个函数:shouldAutorotate(返回NO)和shouldAutorotateToInterfaceOrientation(尽管已弃用)。他们甚至都不叫!看起来没有出路! –

+0

我终于放弃了......检查了我的xib,以便视图以一种合理的方式出现在横向方向上...... :-( –

回答

7

您需要的plist中值设置为所有可能的值,然后限制他们,你认为合适(在导航控制器和TabBar控制器从UIViewController类描述:

在iOS 6中和后,您的应用程序支持在应用程序的Info.plist文件中定义的接口方向 。视图控制器可以覆盖 supportedInterfaceOrientations方法以限制支持方向的列表 。通常,系统在根视图控制器上仅调用此方法 窗口或视图控制器 提交填补整个屏幕;子视图控制器通过他们的父视图 控制器使用为他们提供窗口 部分,不再在决定直接参与什么 旋转的支持。应用程序的方向 蒙版和视图控制器的方向蒙版的交集用于确定视图控制器可以旋转到哪个方向。

+0

因此,您将视图控制器和支持的视口控制器放置在视图控制器中,然后放置在您想要的视图控制器之前旋转一个特定的方式或什么? – jgvb

17

在我的情况下,我有一个新的iOS7应用程序,已经创建了约30个视图控制器。我只需要在一个模态视图控制器上进行自动旋转。我不想更新预先存在的视图控制器。

我选择我的plist中想要的方向:在单模式视图控制器我

@implementation UIViewController (rotate) 
    -(BOOL)shouldAutorotate { 
     return NO; 
    } 
@end 

然后:

select orientations

然后我添加了一个类别,我的应用程序代理上的UIViewController我想加入这个方法:

-(BOOL)shouldAutorotate { 
     return YES; 
} 

我还发现,如果我的视图控制器不是模态VC,我需要在UINavigationController上添加类别方法,而不是在根视图控制器之后的所有VC中,作为视图控制器导航堆栈的一部分 - 类似对此:https://stackoverflow.com/a/20283331/396429

+5

您不应该使用类别来覆盖方法。做完全相同的事情的干净的方式是为您的所有UIViewControllers创建一个基类,并覆盖那里的方法。 – Stoto

+0

我的答案的重点在于展示如何在没有继承UIViewController的情况下实现目标。在某些情况下,这样做是不现实的 –

+3

@Nate,你的答案的全部点是不正确的,因为你的案件是一个特定的,当它的工作时,类别不能用于此。当使用类别覆盖方法时,不能保证它会覆盖它,它仍然可以选择旧方法。 – igrek

1

我遇到过这样的问题 - 在我的应用中只有一个横向视图。 我用下面的代码来处理。

#import "objc/message.h" 
-(void)viewWillAppear:(BOOL)animated{ 

objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationLandscapeLeft); 
} 
+1

喜欢它!黑客和斜杠 – Burf2000

16

简单但它工作得很好。 IOS 7.1和8

AppDelegate.h

@property() BOOL restrictRotation; 

AppDelegate.m

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{ 
if(self.restrictRotation) 
    return UIInterfaceOrientationMaskPortrait; 
else 
    return UIInterfaceOrientationMaskAll; 
} 

的ViewController

-(void) restrictRotation:(BOOL) restriction 
{ 
    AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate; 
    appDelegate.restrictRotation = restriction; 
} 

viewDidLoad中

[self restrictRotation:YES]; or NO 
+0

这是我在那里找到的巧妙解决方案。 我可以补充说,如果在同一个堆栈中,一个视图控制器不受限制,视图控制器的其余部分应该有[self restrictRotation:YES];在viewWillAppear(当你推回按钮。) 谢谢艾伦!你是最好的。 –

0

我知道这是旧的,但我最终在一个更独特的情况下,我们有50+ ViewController遍布应用程序,我拒绝通过并修改和支持相同的方向,但只有一个或2个。我回答我的问题。我创建了一个覆盖 - (BOOL)shouldAutorotate的UIViewController类别,根据设备类型等始终返回NO或YES(这也可以通过支持的接口方向来完成)。然后在我想支持更多然后只是肖像的ViewControllers上,我调用了shouldAutorotate来返回YES。然后用力的方向变化时,视图上的父ViewControllers viewWillAppear中方法驳回使用:

[[UIDevice currentDevice] setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"].

当所有说过和做过,我使用完成的一切,我的几个ViewControllers想与< 30行代码一个用于搅拌的宏。如果我通过在应用程序中的所有VC上替换shouldAutorotate和supportedInterfaceOrientations来完成这项工作,我将拥有250多行代码。并且首先增加了很多烦人的工作。