由于在iOS 6中ShouldAutorotateToInterfaceOrientation
已被弃用,而我之前使用它来强制一个特定的视图仅支持竖屏,那么在iOS 6中正确的做法是什么?这仅适用于我的应用程序中的一个区域,所有其他视图都可以旋转。
由于在iOS 6中ShouldAutorotateToInterfaceOrientation
已被弃用,而我之前使用它来强制一个特定的视图仅支持竖屏,那么在iOS 6中正确的做法是什么?这仅适用于我的应用程序中的一个区域,所有其他视图都可以旋转。
如果你希望所有的导航控制器都遵循顶部视图控制器,你可以使用一个分类(category),这样你就不必逐个更改类名。
@implementation UINavigationController (Rotation_IOS6)
-(BOOL)shouldAutorotate
{
return [[self.viewControllers lastObject] shouldAutorotate];
}
-(NSUInteger)supportedInterfaceOrientations
{
return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}
@end
正如一些评论所指出的那样,这只是一个快速解决问题的方法。更好的解决方案是创建UINavigationController的子类,然后在其中放置这些方法。子类还有助于支持6和7。
"iOS6 By Tutorials"由Ray Wenderlich团队编写,指出了特别适合iOS6的最佳方法 - http://www.raywenderlich.com/,在大多数情况下比子类化UINavigationController
更好。
我正在使用带有UINavigationController
的故事板作为初始视图控制器。
//AppDelegate.m - 不幸的是,在iOS6之前,此方法不可用。
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
//MyViewController.m - 返回您想为每个UIViewController
支持的方向
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
UIViewController *c = [[UIViewController alloc]init];
[self presentModalViewController:c animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
UIViewController
在先前的控制器为横屏的情况下以竖屏方式呈现。UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
UIViewController *c = [[UIViewController alloc]init];
[c.view setBackgroundColor:[UIColor redColor]];
[self.navigationController presentViewController:c animated:NO completion:^{
[self.navigationController dismissViewControllerAnimated:YES completion:^{
}];
}];
}
有趣的是,在编写时,当前或关闭必须进行动画处理。如果两者都没有动画效果,则会出现白屏。不知道为什么这样做可以使其正常工作,但确实如此!视觉效果取决于哪一个被动画化。
我在显示竖屏模态视图时遇到了同样的问题。通常,我会创建一个UINavigationController
,将viewController
设置为rootViewController
,然后将UINavigationController
作为模态视图显示。但是在iOS 6中,viewController
现在会询问navigationController支持的界面方向(默认情况下,iPad支持所有方向,iPhone除了倒置之外都支持)。
解决方案:我不得不子类化UINavigationController
并重写自动旋转方法。有点困难。
- (BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
iOS 5
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
iOS 6
-(BOOL)shouldAutorotate{
return YES;
}
-(NSInteger)supportedInterfaceOrientations{
// UIInterfaceOrientationMaskLandscape;
// 24
//
// UIInterfaceOrientationMaskLandscapeLeft;
// 16
//
// UIInterfaceOrientationMaskLandscapeRight;
// 8
//
// UIInterfaceOrientationMaskPortrait;
// 2
// return UIInterfaceOrientationMaskPortrait;
// or
return 2;
}
我不同意@aprato的回答,因为UIViewController旋转方法是在它们自己的类别中声明的,因此如果您在另一个类别中重写它们,会导致未定义的行为。更安全的做法是在UINavigationController(或UITabBarController)子类中重写它们。
此外,这也没有涵盖从横向视图推入/呈现/弹出到仅支持纵向的VC或反之的情况。 为解决这个棘手问题(从未被苹果公司解决),您应该:
在iOS <= 4和iOS >= 6中:
UIViewController *vc = [[UIViewController alloc]init];
[self presentModalViewController:vc animated:NO];
[self dismissModalViewControllerAnimated:NO];
[vc release];
iOS 5 中:
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
这些将确实强制UIKit重新评估您的shouldAutorotate,supportedInterfaceOrientations等所有内容。
我有一个非常好的方法,将https://dev59.com/b2cs5IYBdhLWcg3w3HoG#13982508和https://dev59.com/tG025IYBdhLWcg3wPzXL#17578272混合使用。
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;
if(self.window.rootViewController){
UIViewController *presentedViewController = [self topViewControllerWithRootViewController:self.window.rootViewController];
orientations = [presentedViewController supportedInterfaceOrientations];
}
return orientations;
}
- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController*)rootViewController;
return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
} else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController*)rootViewController;
return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
} else if (rootViewController.presentedViewController) {
UIViewController* presentedViewController = rootViewController.presentedViewController;
return [self topViewControllerWithRootViewController:presentedViewController];
} else {
return rootViewController;
}
}
并返回您希望为每个UIViewController支持的任何方向
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
presentViewController
以横向方式呈现。使用上面建议的方法,我能够使iPhone ios 5&6正常工作,但出于某种原因,iPad根本不愿意以横向方式呈现。最终,我找到了一个简单的解决方案(在阅读和试错数小时后实施),适用于两个设备和ios 5&6。第1步)在控制器上指定所需的方向(与上述大致相同)。- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
NSInteger mask = UIInterfaceOrientationMaskLandscape;
return mask;
}
-(BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
vc = [[MyViewController alloc]init];
MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc];
[self myNavigationController animated:YES completion:nil];
不想让人感到无聊,您能分享一下您的子类吗?谢谢。
编辑:好了,我终于做到了,子类非常简单。我只需要在AppDelegate
中将navigationController
声明为UINavigationControllerSubclass
而不是默认的UINavigationController
,然后修改您的子类:
- (BOOL)shouldAutorotate {
return _shouldRotate;
}
所以我可以在viewDidLoad
中调用来设置任何视图是否旋转。
_navController = (UINavigationController *)self.navigationController;
[_navController setShouldRotate : YES / NO]
- (NSUInteger)supportedInterfaceOrientations
对于 Monotouch,您可以这样做:
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
return UIInterfaceOrientationMask.LandscapeRight;
}
public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
{
return UIInterfaceOrientation.LandscapeRight;
}