ShouldAutorotateToInterfaceOrientation
,而我使用它强制将特定视图仅设为纵向,因此在iOS 6中执行此操作的正确方法是什么?这仅适用于我的应用程序的一个区域,所有其他视图均可旋转。#1 楼
如果您希望我们所有的导航控制器都尊重顶视图控制器,则可以使用类别,这样就不必遍历并更改一堆类名。@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。
#2 楼
Ray Wenderlich小组在“ iOS6 By Tutorials”(http://www.raywenderlich.com/)中指出了专门针对iOS6的最佳方法,并且在大多数情况下优于对UINavigationController
进行子类化。m将iOS6与包含设置为初始视图控制器的
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;
}
评论
这是iOS 6的最佳解决方案
– Homam
13年5月16日下午5:26
@Phil,它在iOS 6上运行良好。但是在某些情况下,例如,如果您从风景转向肖像,那么它将无法正常工作。知道为什么会发生吗?
–Kirti Nikam
2013年6月25日12:45
非常有用的解决方案。对我来说,最好的。
–奥斯卡·卡斯特隆
13年8月14日在9:35
在iOS 7 beta 6上工作。在我的情况下,从横向到纵向都可以使用。
–马丁·伯格(Martin Berger)
2013年9月3日12:39
我在iOS 6中,但这不起作用。它在“ UIViewController * presentedViewController”行上中断。
– Marcel Marino
13-10-31在16:12
#3 楼
此答案与OP的评论中提出的问题有关:要强制视图以给定方向显示,请将以下内容放入viewWillAppear中:
UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
UIViewController *c = [[UIViewController alloc]init];
[self presentModalViewController:c animated:NO];
[self dismissModalViewControllerAnimated:NO];
}
这是一个小技巧,但是即使以前的控制器是横向的,这也迫使
UIViewController
以纵向显示。iOS7的更新
现已弃用上述方法,因此,对于iOS 7,请使用以下方法:有趣的是,在撰写本文时,必须对当前或关闭进行动画处理。如果两者都不是,则您将获得白屏。不知道为什么这使它起作用,但是它起作用了!视觉效果因动画而异。
评论
谢谢,当我发现有几分钟的空闲时间时,请尝试一下
–希望
13年3月6日在16:58
@RohanAgarwal确实如广告中所述,我在这里使用它。但是您也需要实现接受的答案的代码,否则将无法正常工作。
–丹尼斯·蒙西(Dennis Munsie)
13年5月18日在22:48
有没有人想出如何同时使用正确的旋转动画来完成这项工作?在没有动画的情况下看到它从肖像切换为风景有点不高兴。它可以工作,只是希望使其更好一点。
–丹尼斯·蒙西(Dennis Munsie)
13年5月18日在22:50
@Craig Watkinson在情节提要中不起作用。和presentModalViewController和dismissModalViewControllerAnimated如果我使用presentVirecontroller不推荐使用,那么它将无法正常工作。请帮助我
–卡尔皮什
13年8月22日在9:29
对于ios8,dismissViewControllerAnimated只会崩溃。我发现调用[NWSAppDelegate sharedInstance] .window.rootViewController = nil; [NWSAppDelegate sharedInstance] .window.rootViewController = previousRootController很好用。
– Alexey
2014年9月2日14:36在
#4 楼
因此,在显示仅纵向模式视图时遇到了相同的问题。通常,我将创建一个UINavigationController
,将viewController
设置为rootViewController
,然后将UINavigationController
显示为模态视图。但是,在iOS 6上,viewController
现在将向navigationController询问其支持的界面方向(默认情况下,现在全部用于iPad,而对于iPhone则全部倒置)。 解决方案:我必须继承
UINavigationController
的子类,并重写自动旋转方法。有点la子。 - (BOOL)shouldAutorotate {
return NO;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
// pre-iOS 6 support
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return (toInterfaceOrientation == UIInterfaceOrientationPortrait);
}
评论
在我的上不起作用。我将此代码的全局设置设置为所有方向
– phil88530
2012年9月24日21:00
supportedInterfaceOrientations应该返回NSUInteger,而不是BOOL。请参阅developer.apple.com/library/ios/#featuredarticles/…
–鞭whi
2012年10月9日,下午3:26
它的工作,对我来说,它的tabbarcontroller,再次感谢您的回答
–otakuProgrammer
2012年10月9日在8:27
FWIW,我也必须走这条路。。。谢谢。
–史蒂夫N
2012年11月14日15:07
#5 楼
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;
}
评论
优秀的!需要最大程度地位于此线程的顶部。因为这是解决问题的最简单方法
– Alex
2012年12月24日16:23
@Roshan Jalgaonkar在ios 6中对我不起作用,我只需要按下主页按钮的肖像,如何设置此UIOrientation...。
– Karthik
13年4月29日在12:06
@Karthik,您必须在App的目标中启用受支持的轮播才能使其正常工作。
–亚历杭德罗·伊万(AlejandroIván)
13年7月10日在22:31
@AlejandroIvánk thnx
– Karthik
13年7月11日在4:24
#6 楼
我不同意@aprato的回答,因为UIViewController旋转方法是在类别本身中声明的,因此如果您在另一个类别中进行覆盖,则会导致未定义的行为。在UINavigationController(或UITabBarController)子类中重写它们更安全此外,这还不涉及从“横向”视图推入/呈现/弹出到仅纵向VC或相反的情况。
要解决这个棘手的问题(Apple从未解决过),您应该:
在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等。
评论
无论我使用的是哪个iOS版本,这些崩溃中的第一个对我来说都是如此。说解雇不应该在目前还没结束的情况下被召集。
– arsenius
13年3月27日在7:28
@arsenius您可以张贴一个使用方式的摘要吗?只要没有动画,就不会出现您提到的问题
–拉斐尔·诺布雷(Rafael Nobre)
13年3月27日在17:47
我还将第二个代码段放入viewDidAppear中,它并不能帮助我解决iOS 6上的问题。问题在这里:stackoverflow.com/questions/15654339/…
– arsenius
13年3月28日在5:53
抱歉,这里的最后一条评论。将iOS 5代码移动到viewDidAppear会使用以下输出创建某种无限循环:-[UIApplication beginIgnoringInteractionEvents]溢出。无视。
– arsenius
13年3月28日在6:03
#7 楼
我有一个很好的方法将https://stackoverflow.com/a/13982508/2516436和https://stackoverflow.com/a/17578272/2516436混合在一起-(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;
}
#8 楼
我有一个使用UISplitViewController和UISegmentedController的相对复杂的通用应用程序,并且必须使用presentViewController
在Landscape中显示一些视图。使用上面建议的方法,我能够使iPhone ios 5和6正常工作,但由于某些原因,iPad只是拒绝将其显示为Landscape。最后,我找到了一个适用于设备和ios 5&6的简单解决方案(经过数小时的阅读和反复试验后实施)。步骤1)在控制器上,指定所需的方向(更多信息)或更少,如上文所述)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
-(BOOL)shouldAutorotate
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
NSInteger mask = UIInterfaceOrientationMaskLandscape;
return mask;
}
步骤2)创建一个简单的UINavigationController子类并实现以下方法
-(BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
步骤3)展示您的viewController
vc = [[MyViewController alloc]init];
MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc];
[self myNavigationController animated:YES completion:nil];
希望对某人有帮助。
#9 楼
在这里不要呆板,但您愿意分享您的子类吗?谢谢。edit:好吧,我终于做到了,子类非常简单。我只需要将
navigationController
中的AppDelegate
声明为UINavigationControllerSubclass
而不是默认的UINavigationController
,然后用以下子类修改您的子类:- (BOOL)shouldAutorotate {
return _shouldRotate;
}
,这样我可以设置任何我想要的视图请致电
viewDidLoad
旋转或不旋转_navController = (UINavigationController *)self.navigationController;
[_navController setShouldRotate : YES / NO]
希望此调整对其他人也有帮助,谢谢您的提示!
提示:充分利用of
- (NSUInteger)supportedInterfaceOrientations
在您的视图控制器中,所以您最终不会在横向中拥有人像所需的视图,反之亦然。
#10 楼
我没有亲自测试它,但是文档指出您现在可以覆盖这些方法:supportedInterfaceOrientations
和preferredInterfaceOrientationForPresentation
。您可能可以实现所需的y,只需在这些方法中设置所需的方向即可。 #11 楼
使用子类或类别的答案允许UINavigationController和UITabBarController类中的VC很好地工作。从横向选项卡栏控制器启动仅纵向模式时失败。如果需要执行此操作,请使用显示和隐藏非动画模式视图的技巧,但可以在viewDidAppear方法中进行。在viewDidLoad或viewWillAppear中对我不起作用。除此之外,上述解决方案都可以正常工作。
#12 楼
对于Monotouch,您可以这样操作:public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
{
return UIInterfaceOrientationMask.LandscapeRight;
}
public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
{
return UIInterfaceOrientation.LandscapeRight;
}
#13 楼
我看到了很多答案,但没有得到关于方向的特定想法和答案,但是看到链接很好地理解了方向,并删除了ios6的强制旋转。http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/
我认为这是完整的帮助。 br />
#14 楼
只需转到project.plist,然后添加支持的界面方向,然后仅添加Portrait(底部主页按钮)和Portrait(顶部主页按钮)即可。您可以根据项目要求在其中添加或删除方向。
谢谢
评论
它不是针对整个应用程序的特定视图控制器。
–穆罕默德·里兹旺(Muhammad Rizwan)
2014年8月20日在12:47
#15 楼
1)检查项目设置和info.plist,并确保仅选择了所需的方向。2)将以下方法添加到顶部视图控制器(导航控制器/标签栏控制器)
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
3)将以下方法添加到您的应用程序委托中
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait;
}
#16 楼
将其放在每个不想旋转的ViewController
的.m文件中:- (NSUInteger)supportedInterfaceOrientations
{
//return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
return UIInterfaceOrientationMaskPortrait;
}
有关更多信息,请参见此处。
评论
我可以确认这项工作。如果愿意,您也可以将“ [self.viewControllers lastObject]”替换为“ self.topViewController”。
–Wayne Liu
2012-09-23 9:02
如果您使用的是UITabBarController,则此UINavigationController类别无济于事。您应该改为在UITabBarController上进行分类...
– Borut Tomazin
2012年10月1日在8:57
这种解决方案的问题是,当您弹出横向控制器时,并且新的顶级控制器仅支持纵向(反之亦然)时,该解决方案将不起作用,在这种情况下,不会调用这些回调,我还想找到方法迫使新的顶部控制器进入正确的方向。有任何想法吗?
–希望
2012年10月6日上午10:21
我将UINavigationController子类化,并将其设置为window.rootController。我实现了所有3种方法,当您更改设备的旋转时效果很好,问题是当您弹出视图控制器时会调用这些方法(与旋转无关)
–希望
2012年10月7日在22:43
如果我正在从景观视图控制器执行推入或弹出操作,则此强制UIViewController会变为景观。但是,如果我旋转成人像,则可以正常工作,并且永远不会变成风景。从横向推入或弹出时唯一的问题。请帮忙
–塔里克语
13年1月30日在16:30