ios 旋转在 iOS6 上表现不同
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12536645/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rotation behaving differently on iOS6
提问by Marcal
I did an App which is tab-based. Nothing needs to be on landscape mode but a couple of views. It worked OK on iOS5 and I was pretty happy with the result. However with iOS6 and without messing with anything, it now rotates all the views and the consequences are not nice.
我做了一个基于选项卡的应用程序。无需在横向模式下进行任何操作,只需要几个视图即可。它在 iOS5 上运行良好,我对结果非常满意。然而,在 iOS6 中,没有任何问题,它现在旋转所有视图,结果并不好。
Because its a tab-based app, the couple of view I need in landscape are modalViews. That way I didn't mess with the tabbar and I had only to chose portrait in the "Supported Orientations" setting on build options and set:
因为它是一个基于选项卡的应用程序,所以我在横向中需要的几个视图是 modalViews。这样我就不会弄乱标签栏,我只需要在构建选项的“支持的方向”设置中选择纵向并设置:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
on the views I wanted landscape.
关于我想要风景的意见。
Now with iOS6 this views are also on portrait mode, no matter what and they do not show the landscape mode even if I rotate the device. Likewise, if I allow all the orientations on the "Supported orientations", they all rotate, no matter what I put on the method above.
现在,在 iOS6 中,此视图也处于纵向模式,无论如何,即使我旋转设备,它们也不会显示横向模式。同样,如果我允许“支持的方向”上的所有方向,它们都会旋转,无论我在上面的方法上放什么。
On all the views I haven't check the box "Use Autolayout" on storyboards.
在所有视图中,我都没有选中故事板上的“使用自动布局”框。
Any help here?
这里有什么帮助吗?
*EDIT**Now that I see it, the App I have on the device works fine. I've installed with a promo code, not from Xcode, only to see whether my customers are having problems or not. Fortunatelly they are not. The problem remains though.
*编辑**现在我看到了,我在设备上的应用程序运行良好。我安装了促销代码,而不是来自 Xcode,只是为了看看我的客户是否有问题。幸运的是他们不是。问题仍然存在。
回答by iMathieuB
The most important part of the documentation I found for this issue is:
我为这个问题找到的文档中最重要的部分是:
When the user changes the device orientation, the system calls this method on the root view controller or the topmost presented view controller that fills the window
当用户改变设备方向时,系统调用根视图控制器上或填充所述窗口这种方法最上面的呈现视图控制器
To make my app fully working for autorotation in iOS 6, I had to do the following:
为了使我的应用程序完全适用于 iOS 6 中的自动旋转,我必须执行以下操作:
1) I created a new subclass of UINavigationController, and added shouldAutorotate and supportedInterfaceOrientation methods:
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) In the AppDelegate, I did use my new subclass to show my root ViewController (it is introScreenViewController, a UIViewController subclass) and did set the self.window.rootViewController, so it looks that:
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];
回答by Prcela
This is the alternative solution for iOS6in case you are using the tab bar controller. It also shows that is NOT needed to override UINavigationController or even UITabBarController.
如果您使用标签栏控制器,这是iOS6的替代解决方案。它还表明不需要覆盖 UINavigationController 甚至 UITabBarController。
In your xyzAppDelegate.hadd this interface:
在你的xyzAppDelegate.h添加这个接口:
@interface UITabBarController (MyApp)
@end
And in xyzAppDelegate.madd these methods:
在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
Also, set the root view controller for the app window:
此外,为应用程序窗口设置根视图控制器:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
[self.window setRootViewController:tabBarController];
回答by Mike M
Are you setting the rootViewController in the delegate? For example,
您是否在委托中设置了 rootViewController?例如,
self.window.rootViewController = self.navigationController;
When I was doing some iOS6 testing it wouldn't work properly until I did that...
当我进行一些 iOS6 测试时,它无法正常工作,直到我这样做......
回答by Luke
I have a good solution for cross 5.0 to 6.0 working - All of the above with
我有一个很好的跨 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
}
回答by Maurice
This is what works for me.
这对我有用。
I created a new subclass of UINavigationController, and added shouldAutorotate and supportedInterfaceOrientation methods:
我创建了一个新的 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
Then add this to your delegate
然后将此添加到您的委托
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];
Now you can add this to the views you want to rotate in all orientations
现在您可以将其添加到您想要在所有方向旋转的视图中
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
-(BOOL)shouldAutorotate
{
return YES;
}
Or add this to the views you only want to go portrait and portraitUpsideDown
或者将此添加到您只想纵向和纵向颠倒的视图中
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return
(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown ;
}
- (BOOL)shouldAutorotate
{
return YES;
}
回答by thanhbinh84
You might double check Support Interface Orientations
您可能会仔细检查支持接口方向
On previous version, it means nothing, but affects whole application now.
在以前的版本中,它没有任何意义,但现在会影响整个应用程序。
Note: The 'upside down' option doesn't work even enabled or disabled on iOS 6.
注意:“颠倒”选项即使在 iOS 6 上启用或禁用也不起作用。
回答by Hot Licks
Did a little experimentation: Took an existing app (that wouldn't rotate in iOS-6, but did previously) and added the one line self.window.rootViewController = navCtlr;
to AppDelegate. This resulted in an app that appears (at least at first blush) to rotate just fine.
做了一些实验:使用一个现有的应用程序(在 iOS-6 中不会旋转,但以前会旋转)并将一行添加self.window.rootViewController = navCtlr;
到 AppDelegate。这导致应用程序看起来(至少在第一次脸红)旋转得很好。
Then, out of curiosity, I created the RotationCanary class and plugged an instance of that into self.window.rootViewController. I'd start up the app and wait for the inevitable "unrecognized selector", create a new method of that name in RotationCanary, and re-run. The new method would call the realnav ctlr and log its response before returning it. This produced (sooner than I expected) the following log:
然后,出于好奇,我创建了 RotationCanary 类并将它的一个实例插入到 self.window.rootViewController 中。我会启动应用程序并等待不可避免的“无法识别的选择器”,在 RotationCanary 中创建一个具有该名称的新方法,然后重新运行。新方法将调用真正的导航 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
Curiously, the class was never actually invoked to perform rotation -- only during setup.
奇怪的是,该类实际上从未被调用来执行旋转——仅在设置期间。
I suspect thatApple uses the setting of rootViewController purely as a way to indicate that the app has been modified for iOS 6 rotation -- it has no real function otherwise.
我怀疑,苹果使用RootViewController的的设置纯粹,以此来表明该应用程序已被修改为iOS 6的旋转-它没有真正的功能并非如此。
FWIW:It occurred to me that the caller might be using respondsToSelector
and skipping some calls, so I added an implementation of resolveInstanceMethod:
to RotationCanary, to trap any such attempts. None occurred.
FWIW:我突然想到调用者可能正在使用respondsToSelector
并跳过一些调用,所以我添加了resolveInstanceMethod:
RotationCanary的实现,以捕获任何此类尝试。无发生。
回答by Snowcrash
From Apple's documentation for shouldAutorotateToInterfaceOrientation:
来自 Apple 的 shouldAutorotateToInterfaceOrientation 文档:
Override the supportedInterfaceOrientations and preferredInterfaceOrientationForPresentation methods instead.
改写 supportedInterfaceOrientations 和 preferredInterfaceOrientationForPresentation 方法。
回答by Pautex
For app "Same Picture" on iOS6 I need an orientation change, my UIViewController never be informed for orientation, it's an photo overlay likely didrotate works well :
对于 iOS6 上的应用程序“相同图片”,我需要更改方向,我的 UIViewController 永远不会被告知方向,这是一个照片叠加层,可能 didrotate 效果很好:
- (void)didRotate: ( NSNotification* )note
{
[self performSelector:@selector(rotateRecalculDiffere) withObject:nil afterDelay:0.3 ];
}
I make fine size adjust with delayed call. From notification it's easy to know final orientation
我通过延迟呼叫进行精细尺寸调整。从通知中很容易知道最终方向
回答by dhaya
This code common for ios5 and ios6
此代码适用于 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;
}