La rotación se comporta de manera diferente en iOS6

Hice una aplicación basada en tabs. No es necesario que haya nada en el modo paisaje, sino un par de vistas. Funcionó bien en iOS5 y estaba muy contento con el resultado. Sin embargo, con iOS6 y sin meterse con nada, ahora rota todas las vistas y las consecuencias no son buenas.

Debido a que es una aplicación basada en tabs, el par de vistas que necesito en el paisaje son modalViews. De esa manera no me metí con la barra de tabs y solo tuve que elegir el retrato en la configuración de “Orientaciones admitidas” en las opciones de creación y establecer:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft); return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); } 

en las vistas que quería paisaje.

Ahora con iOS6 estas vistas también están en modo vertical, no importa qué y no muestran el modo horizontal incluso si giro el dispositivo. Del mismo modo, si permito todas las orientaciones en las “Orientaciones admitidas”, todas giran, independientemente de lo que puse en el método anterior.

En todas las vistas, no he marcado la casilla “Usar el diseño automático” en los guiones gráficos.

¿Alguna ayuda aquí?

* EDITAR ** Ahora que lo veo, la aplicación que tengo en el dispositivo funciona bien. He instalado un código de promoción, no de Xcode, solo para ver si mis clientes tienen problemas o no. Afortunadamente no lo son. El problema permanece sin embargo.

La parte más importante de la documentación que encontré para este problema es:

Cuando el usuario cambia la orientación del dispositivo, el sistema llama a este método en el controlador de vista raíz o en el controlador de vista presentado más arriba que llena la ventana

Para hacer que mi aplicación funcione completamente para autorrotación en iOS 6, tuve que hacer lo siguiente:

1) Creé una nueva subclase de UINavigationController y agregué los métodos shouldAutorotate y supportedInterfaceOrientation:

 // MyNavigationController.h: #import  @interface MyNavigationController : UINavigationController @end // MyNavigationController.m: #import "MyNavigationController.h" @implementation MyNavigationController ... - (BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } ... @end 

2) En AppDelegate, utilicé mi nueva subclase para mostrar mi raíz ViewController (es introScreenViewController, una subclase UIViewController) y configuré el auto.window.rootViewController, por lo que parece que:

  nvc = [[MyNavigationController alloc] initWithRootViewController:introScreenViewController]; nvc.navigationBarHidden = YES; self.window.rootViewController = nvc; [window addSubview:nvc.view]; [window makeKeyAndVisible]; 

Esta es la solución alternativa para iOS6 en caso de que esté utilizando el controlador de la barra de tabs. También muestra que NO es necesario para anular UINavigationController o incluso UITabBarController.

En su xyzAppDelegate.h agregue esta interfaz:

 @interface UITabBarController (MyApp) @end 

Y en xyzAppDelegate.m agregue estos métodos:

 @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 

Además, configure el controlador de vista raíz para la ventana de la aplicación:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... [self.window setRootViewController:tabBarController]; 

¿Estás configurando el rootViewController en el delegado? Por ejemplo,

  self.window.rootViewController = self.navigationController; 

Cuando estaba haciendo algunas pruebas iOS6 no funcionaría correctamente hasta que lo hice …

Tengo una buena solución para el trabajo de 5.0 a 6.0 – Todo lo anterior con

 -(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 } 

Puede verificar las orientaciones de la interfaz de soporte

enter image description here

En la versión anterior, no significa nada, pero afecta toda la aplicación ahora.

Nota: La opción ‘al revés’ no funciona incluso habilitada o deshabilitada en iOS 6.

Esto es lo que funciona para mí.

Creé una nueva subclase de UINavigationController y agregué los métodos shouldAutorotate y 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 

Luego agrega esto a tu delegado

 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]; 

Ahora puede agregar esto a las vistas que desea rotar en todas las orientaciones

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } -(NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } -(BOOL)shouldAutorotate { return YES; } 

O agregue esto a las vistas a las que solo quiere ir portrait and portraitUpsideDown

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown); } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown ; } - (BOOL)shouldAutorotate { return YES; } 

Hay algunas cosas que debe manejar para que esto funcione, ya que con iOS6, la estructura de autorrotación ha cambiado. La estructura de cómo se determina la autorotación se revierte ahora. Solía ​​ser que un controlador de vista individual puede controlar el autorroteo con su decisión, pero ahora el “mayor autoritario” lo determina el padre más alto en la navegación, que en su caso es el tabBar.

  1. Debe asegurarse de que su ventana tenga un conjunto de control de raíz y no solo se haya agregado como una subvista.
  2. Es posible que necesite subclasificar su tabBarController para implementar tanto “supportedInterfaceOrientations” como “shouldAutorotate”.
  3. Si hay algún viewControllers que necesite comportarse de manera diferente, entonces necesitará que su tabBarController consulte con ellos para obtener una respuesta sobre si deberían o no autorrotar.

por ejemplo:

 - (BOOL)shouldAutorotate { return self.selectedViewController.shouldAutorotate; } 

y en su controlador de vista implementaría shouldAutorotate y tomaría la decisión allí.

De la documentación de Apple para shouldAutorotateToInterfaceOrientation:

En su lugar, sustituya las metodologías SupportInterfaceOrientations y preferredInterfaceOrientationForPresentation.

http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/occ/instm/UIViewController/shouldAutorotateToInterfaceOrientation :

Para la aplicación “Misma imagen” en iOS6, necesito un cambio de orientación, mi UIViewController nunca recibe información sobre la orientación, es probable que una superposición de fotos funcione bien:

 - (void)didRotate: ( NSNotification* )note { [self performSelector:@selector(rotateRecalculDiffere) withObject:nil afterDelay:0.3 ]; } 

Hago ajustes de tamaño fino con llamadas demoradas. De la notificación es fácil saber la orientación final

Hice un poco de experimentación: Tomó una aplicación existente (que no rotaría en iOS-6, pero lo hizo anteriormente) y agregó una línea self.window.rootViewController = navCtlr; a AppDelegate. Esto resultó en una aplicación que aparece (al menos a primera vista) para rotar bien.

Luego, por curiosidad, creé la clase RotationCanary y conecté una instancia de eso en self.window.rootViewController. Comenzaría la aplicación y esperaría el inevitable “selector no reconocido”, crearía un nuevo método con ese nombre en RotationCanary y lo volvería a ejecutar. El nuevo método llamaría a la navegación real ctlr y registraría su respuesta antes de devolverla. Esto produjo (antes de lo esperado) el siguiente registro:

 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]  Entering Method -[DetailViewController viewDidLoad] 2012-12-07 13:08:47.706 MyTestApp[53328:c07]  Entering Method -[SplitContentViewController viewDidLoad] 2012-12-07 13:08:47.708 MyTestApp[53328:c07]  Entering Method -[FamilyMasterViewController viewDidLoad] 2012-12-07 13:08:47.709 MyTestApp[53328:c07]  Entering Method -[MasterViewController viewDidLoad] 2012-12-07 13:08:47.718 MyTestApp[53328:c07]  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 = > 2012-12-07 13:08:47.825 MyTestApp[53328:c07] -[RotationCanary view] - view = > 2012-12-07 13:08:47.826 MyTestApp[53328:c07] -[RotationCanary view] - view = > 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 = > 2012-12-07 13:08:47.830 MyTestApp[53328:c07] -[RotationCanary _tryBecomeRootViewControllerInWindow:] - window = >, result = YES 2012-12-07 13:08:47.916 MyTestApp[53328:c07] -[RotationCanary _deepestDefaultFirstResponder] - result =  2012-12-07 13:08:47.916 MyTestApp[53328:c07] Device model: x86_64 

Curiosamente, la clase nunca se invocó para realizar la rotación, solo durante la configuración.

Sospecho que Apple usa la configuración de rootViewController puramente como una forma de indicar que la aplicación se ha modificado para la rotación de iOS 6; de lo contrario, no tiene ninguna función real.

FWIW: Se me ocurrió que la persona que llama podría estar usando respondsToSelector y omitir algunas llamadas, así que agregué una implementación de resolveInstanceMethod: a RotationCanary, para interceptar cualquier bash de este tipo. Ninguna ocurrió

La autorrotación cambió en iOS 6.0. Verifique este enlace para más información.

La autorotación está cambiando en iOS 6. En iOS 6, el método shouldAutorotateToInterfaceOrientation: de UIViewController está en desuso. En su lugar, debe usar las Orientaciones de interfase compatibles y los métodos de Autorotar.

Este código es común para ios5 y 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; }