我做了一个基于标签的应用程序。没有什么需要在横向模式上,但有几个观点。它在iOS5上运行正常,我对结果非常满意。然而,对于iOS6而且没有任何混乱,它现在旋转所有视图,后果不太好。
因为它是一个基于标签的应用程序,所以我在横向上需要的几个视图是modalViews。这样我就没有搞乱tabbar,我只能在构建选项的“Supported Orientations”设置中选择portrait并设置:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
关于我想要的景观。
现在使用iOS6,这个视图也处于纵向模式,无论如何,即使我旋转设备它们也不显示横向模式。同样,如果我允许“支持的方向”上的所有方向,它们都会旋转,无论我在上面的方法中使用什么。
在所有视图中,我没有在故事板上选中“使用Autolayout”框。
这里有任何帮助吗?
*的 修改 ** 现在,我看到它,我在设备上的应用程序工作正常。我安装了促销代码,而不是来自Xcode,只是为了看我的客户是否有问题。幸运的是,他们不是。问题仍然存在。
答案 0 :(得分:36)
我在这个问题上找到的文档中最重要的部分是:
当用户更改设备方向时,系统会调用此方法 根视图控制器或最顶层呈现视图上的方法 填充窗口的控制器
为了让我的应用程序完全适用于iOS 6中的自动旋转,我必须执行以下操作:
1)我创建了一个新的UINavigationController子类,并添加了shouldAutorotate和supportedInterfaceOrientation方法:
// MyNavigationController.h:
#import <UIKit/UIKit.h>
@interface MyNavigationController : UINavigationController
@end
// MyNavigationController.m:
#import "MyNavigationController.h"
@implementation MyNavigationController
...
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskAll;
}
...
@end
2)在AppDelegate中,我确实使用了我的新子类来显示我的根ViewController(它是introScreenViewController,一个UIViewController子类)并设置了self.window.rootViewController,所以看起来:
nvc = [[MyNavigationController alloc] initWithRootViewController:introScreenViewController];
nvc.navigationBarHidden = YES;
self.window.rootViewController = nvc;
[window addSubview:nvc.view];
[window makeKeyAndVisible];
答案 1 :(得分:10)
如果您使用标签栏控制器,这是 iOS6 的替代解决方案。它还表明不需要覆盖UINavigationController甚至UITabBarController。
在 xyzAppDelegate.h 中添加此界面:
@interface UITabBarController (MyApp)
@end
在 xyzAppDelegate.m 中添加以下方法:
@implementation UITabBarController (MyApp)
-(BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
// your custom logic for rotation of selected tab
if (self.selectedIndex==...) {
return UIInterfaceOrientationMaskAll;
}
else {
return UIInterfaceOrientationMaskPortrait|UIInterfaceOrientationMaskPortraitUpsideDown;
}
}
@end
另外,为应用程序窗口设置根视图控制器:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
[self.window setRootViewController:tabBarController];
答案 2 :(得分:6)
您是否在委托中设置了rootViewController?例如,
self.window.rootViewController = self.navigationController;
当我做一些iOS6测试时,直到我这样做才能正常工作......
答案 3 :(得分:5)
我有一个很好的解决方案,适用于5.0到6.0的工作 - 以上所有
-(BOOL)shouldAutorotate{return [self shouldIRotateAnyiOS];}//iOS6
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{return [self shouldIRotateAnyiOS];}//pre iOS6
-(BOOL)shouldIRotateAnyiOS{
UIInterfaceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
//do the rotation stuff
return YES
}
答案 4 :(得分:1)
您可以仔细检查支持界面方向
在以前的版本中,它没有任何意义,但现在影响整个应用程序。
注意:即使在iOS 6上启用或禁用“倒置”选项也无效。
答案 5 :(得分:1)
这对我有用。
我创建了一个新的UINavigationController子类,并添加了shouldAutorotate和supportedInterfaceOrientation方法:
#import "MyNavigationController.h"
@interface MyNavigationController ()
@end
@implementation MyNavigationController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotate {
return [self.visibleViewController shouldAutorotate];
}
- (NSUInteger)supportedInterfaceOrientations {
return [self.visibleViewController supportedInterfaceOrientations];
}
@end
然后将其添加到您的代理
UINavigationController *nvc = [[MyNavigationController alloc] initWithRootViewController:_viewController];
nvc.navigationBarHidden = NO; // YES if you want to hide the navigationBar
self.window.rootViewController = nvc;
[_window addSubview:nvc.view];
[_window makeKeyAndVisible];
现在,您可以将其添加到要在所有方向上旋转的视图
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
-(BOOL)shouldAutorotate
{
return YES;
}
或者将此添加到您只想要肖像和portraitUpsideDown
的视图中- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return
(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown ;
}
- (BOOL)shouldAutorotate
{
return YES;
}
答案 6 :(得分:0)
iOS 6.0中的自动旋转已更改。有关详细信息,请查看此link。
iOS 6中的自动旋转正在发生变化。在iOS 6中,shouldAutorotateToInterfaceOrientation: 不推荐使用UIViewController的方法。在它的位置,你应该使用 supportedInterfaceOrientations和shouldAutorotate方法。
答案 7 :(得分:0)
为了实现这一点,您可能需要处理一些事情,因为在iOS6中,自动旋转的结构已经发生了变化。现在可以逆转自动旋转的结构。过去,个别视图控制器可以通过其决定来控制自动旋转,但现在“shouldAutorotate”由导航中的最高父级确定,在您的情况下是tabBar。
例如:
- (BOOL)shouldAutorotate
{
return self.selectedViewController.shouldAutorotate;
}
并在您的视图控制器中,您将实现shouldAutorotate并在那里做出决定。
答案 8 :(得分:0)
此代码适用于ios5和ios6
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
[self performSelector:@selector(setframeLandscap) withObject:nil afterDelay:0.2];
}
else {
[self performSelector:@selector(setframePortrait) withObject:nil afterDelay:0.2];
}
}
-(BOOL)shouldAutorotate {
return YES;
}
答案 9 :(得分:0)
来自Apple的shouldAutorotateToInterfaceOrientation文档:
改为使用supportedInterfaceOrientations和preferredInterfaceOrientationForPresentation方法。
答案 10 :(得分:0)
对于iOS6上的应用程序“相同图片”我需要更改方向,我的UIViewController永远不会被告知方向,这是一个照片叠加可能didrotate运作良好:
- (void)didRotate: ( NSNotification* )note
{
[self performSelector:@selector(rotateRecalculDiffere) withObject:nil afterDelay:0.3 ];
}
我通过延迟通话调整大小。从通知中可以很容易地知道最终定位
答案 11 :(得分:0)
做了一些实验:取了一个现有的应用程序(不会在iOS-6中旋转,但之前会这样做)并将一行self.window.rootViewController = navCtlr;
添加到AppDelegate。这导致一个应用程序出现(至少乍一看)旋转得很好。
然后,出于好奇,我创建了RotationCanary类并将其实例插入self.window.rootViewController。我启动应用程序并等待不可避免的“无法识别的选择器”,在RotationCanary中创建该名称的新方法,然后重新运行。新方法将调用 real nav ctlr并在返回之前记录其响应。这产生了(比我预期的更早)以下日志:
2012-12-07 13:08:47.689 MyTestApp[53328:c07] System Version is 6.0; Supported versions are 5.0.x to 6.0.x
2012-12-07 13:08:47.691 MyTestApp[53328:c07] Host memory (in bytes) used: 3489513472 free: 803893248 total: 4293406720
2012-12-07 13:08:47.692 MyTestApp[53328:c07] Memory in use by task (in bytes): 23719936
2012-12-07 13:08:47.695 MyTestApp[53328:c07] Creating database
2012-12-07 13:08:47.699 MyTestApp[53328:c07] Item Selected: (null) (null)
2012-12-07 13:08:47.700 MyTestApp[53328:c07] <DetailViewController.m:(27)> Entering Method -[DetailViewController viewDidLoad]
2012-12-07 13:08:47.706 MyTestApp[53328:c07] <SplitContentViewController.m:(57)> Entering Method -[SplitContentViewController viewDidLoad]
2012-12-07 13:08:47.708 MyTestApp[53328:c07] <FamilyMasterViewController.m:(32)> Entering Method -[FamilyMasterViewController viewDidLoad]
2012-12-07 13:08:47.709 MyTestApp[53328:c07] <MasterViewController.m:(41)> Entering Method -[MasterViewController viewDidLoad]
2012-12-07 13:08:47.718 MyTestApp[53328:c07] <FamilyHomeDetailViewController.m:(51)> Entering Method -[FamilyHomeDetailViewController viewDidLoad]
2012-12-07 13:08:47.820 MyTestApp[53328:c07] -[RotationCanary _preferredInterfaceOrientationGivenCurrentOrientation:] - current = 2, result = 2
2012-12-07 13:08:47.821 MyTestApp[53328:c07] -[RotationCanary _existingView] - view = (null)
2012-12-07 13:08:47.824 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.825 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.826 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.827 MyTestApp[53328:c07] -[RotationCanary wantsFullScreenLayout] - result = YES
2012-12-07 13:08:47.827 MyTestApp[53328:c07] -[RotationCanary view] - view = <UILayoutContainerView: 0x9c987f0; frame = (0 0; 768 1024); autoresize = W+H; layer = <CALayer: 0x9c8fa00>>
2012-12-07 13:08:47.830 MyTestApp[53328:c07] -[RotationCanary _tryBecomeRootViewControllerInWindow:] - window = <UIWindow: 0x9c76320; frame = (0 0; 768 1024); opaque = NO; autoresize = RM+BM; layer = <UIWindowLayer: 0x9c76450>>, result = YES
2012-12-07 13:08:47.916 MyTestApp[53328:c07] -[RotationCanary _deepestDefaultFirstResponder] - result = <SignOnViewController: 0x9c942a0>
2012-12-07 13:08:47.916 MyTestApp[53328:c07] Device model: x86_64
奇怪的是,这个类实际上从未被调用来执行旋转 - 仅在设置期间。
我怀疑 Apple使用rootViewController的设置纯粹表示该应用已被修改为iOS 6轮换 - 否则它没有真正的功能。
FWIW:我发现调用者可能正在使用respondsToSelector
并跳过一些调用,因此我向RotationCanary添加了resolveInstanceMethod:
的实现,以捕获任何此类调用尝试。没有发生。