Como ShouldAutorotateToInterfaceOrientation
está obsoleto en iOS 6 y lo usé para forzar una vista particular a solo vertical , ¿cuál es la forma correcta de hacer esto en iOS 6? Esto es solo para un área de mi aplicación, todas las demás vistas pueden rotar.
ios
xcode
ios6
xamarin.ios
Neal
fuente
fuente
La mejor forma para iOS6 se indica específicamente en "iOS6 por tutoriales" del equipo de Ray Wenderlich - http://www.raywenderlich.com/ y es mejor que la subclasificación
UINavigationController
en la mayoría de los casos.Estoy usando iOS6 con un guión gráfico que incluye un
UINavigationController
conjunto como controlador de vista inicial.//AppDelegate.m: desafortunadamente, este método no está disponible antes de 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: devuelve las orientaciones que quieras admitir para cada
UIViewController
- (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; }
fuente
Esta respuesta se relaciona con las preguntas formuladas en los comentarios de la publicación del OP:
Para forzar que una vista aparezca en una orientación determinada, ponga lo siguiente en viewWillAppear:
UIApplication* application = [UIApplication sharedApplication]; if (application.statusBarOrientation != UIInterfaceOrientationPortrait) { UIViewController *c = [[UIViewController alloc]init]; [self presentModalViewController:c animated:NO]; [self dismissModalViewControllerAnimated:NO]; }
Es un truco, pero esto obliga
UIViewController
a que se presente en vertical incluso si el controlador anterior era horizontal.ACTUALIZAR para iOS7
Los métodos anteriores ahora están en desuso, por lo que para iOS 7 use lo siguiente:
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:^{ }]; }]; }
Curiosamente, en el momento de la escritura, ya sea presente o despedir debe estar animada. Si ninguno de los dos lo está, obtendrá una pantalla en blanco. No tengo idea de por qué esto lo hace funcionar, ¡pero lo hace! El efecto visual es diferente según el que esté animado.
fuente
Así que me encontré con el mismo problema al mostrar vistas modales solo de retrato. Normalmente, crearía un
UINavigationController
, establecería elviewController
como elrootViewController
y luego lo mostraríaUINavigationController
como una vista modal. Pero con iOS 6, elviewController
ahora le pedirá al navigationController las orientaciones de interfaz compatibles (que, de forma predeterminada, ahora es todo para iPad y todo menos al revés para iPhone).Solución : tuve que crear una subclase
UINavigationController
y anular los métodos de autorrotación. Algo cojo.- (BOOL)shouldAutorotate { return NO; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } // pre-iOS 6 support - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return (toInterfaceOrientation == UIInterfaceOrientationPortrait); }
fuente
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; }
fuente
No estoy de acuerdo con la respuesta de @aprato, porque los métodos de rotación de UIViewController se declaran en las categorías mismas, lo que da como resultado un comportamiento indefinido si anula luego en otra categoría. Es más seguro anularlos en una subclase UINavigationController (o UITabBarController)
Además, esto no cubre el escenario en el que empuja / presenta / emerge desde una vista horizontal a un VC solo vertical o viceversa. Para resolver este difícil problema (nunca abordado por Apple), debe:
En iOS <= 4 y iOS> = 6:
UIViewController *vc = [[UIViewController alloc]init]; [self presentModalViewController:vc animated:NO]; [self dismissModalViewControllerAnimated:NO]; [vc release];
En iOS 5:
UIWindow *window = [[UIApplication sharedApplication] keyWindow]; UIView *view = [window.subviews objectAtIndex:0]; [view removeFromSuperview]; [window addSubview:view];
Estos REALMENTE obligarán a UIKit a reevaluar todas sus orientaciones shouldAutorotate, supportedInterfaceOrientations, etc.
fuente
Tengo un muy buen enfoque mezclando https://stackoverflow.com/a/13982508/2516436 y 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; } }
y devuelva las orientaciones que desee apoyar para cada UIViewController
- (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; }
fuente
Tengo una aplicación universal relativamente compleja que usa UISplitViewController y UISegmentedController, y tengo algunas vistas que deben presentarse en Landscape usando
presentViewController
. Usando los métodos sugeridos anteriormente, pude hacer que el iPhone ios 5 y 6 funcionaran de manera aceptable, pero por alguna razón el iPad simplemente se negó a presentarse como Paisaje. Finalmente, encontré una solución simple (implementada después de horas de lectura y prueba y error) que funciona tanto para dispositivos como para ios 5 y 6.Paso 1) En el controlador, especifique la orientación requerida (más o menos como se indica arriba)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); } -(BOOL)shouldAutorotate { return YES; } -(NSUInteger)supportedInterfaceOrientations { NSInteger mask = UIInterfaceOrientationMaskLandscape; return mask; }
Paso 2) Cree una subclase UINavigationController simple e implemente los siguientes métodos
-(BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; }
Paso 3) Presenta tu viewController
vc = [[MyViewController alloc]init]; MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc]; [self myNavigationController animated:YES completion:nil];
Espero que esto sea útil para alguien.
fuente
No quiero ser aburrido aquí, pero ¿sería tan amable de compartir su subclase? Gracias.
editar: bueno, finalmente lo hice, la subclase era muy simple de hacer. Solo tuve que declarar el
navigationController
enAppDelegate
como enUINavigationControllerSubclass
lugar del predeterminadoUINavigationController
, luego modifiqué su subclase con:- (BOOL)shouldAutorotate { return _shouldRotate; }
para que pueda configurar cualquier vista que quiera rotar o no llamando al
viewDidLoad
_navController = (UINavigationController *)self.navigationController; [_navController setShouldRotate : YES / NO]
Espero que este ajuste ayude a otros también, ¡gracias por tu consejo!
Consejo: utilice
- (NSUInteger)supportedInterfaceOrientations
en sus controladores de vista, para que no termine teniendo una vista vertical deseada en horizontal o viceversa.
fuente
No lo probé yo mismo, pero la documentación indica que ahora puede anular esos métodos:
supportedInterfaceOrientations
ypreferredInterfaceOrientationForPresentation
.Probablemente pueda lograr lo que desea y establecer solo la orientación que desee en esos métodos.
fuente
Las respuestas que usan subclases o categorías para permitir VC dentro de las clases UINavigationController y UITabBarController funcionan bien. Error al iniciar un modo de solo retrato desde un controlador de barra de pestañas horizontal. Si necesita hacer esto, utilice el truco de mostrar y ocultar una vista modal no animada, pero hágalo en el método viewDidAppear . No funcionó para mí en viewDidLoad o viewWillAppear.
Aparte de eso, las soluciones anteriores funcionan bien.
fuente
Para Monotouch, puede hacerlo de esta manera:
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations() { return UIInterfaceOrientationMask.LandscapeRight; } public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation() { return UIInterfaceOrientation.LandscapeRight; }
fuente
Veo muchas respuestas, pero no entiendo la idea en particular y la respuesta sobre la orientación, pero veo el enlace bien, entiendo la orientación y elimino la rotación forzada para ios6.
http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/
Creo que es una ayuda completa.
fuente
Simplemente vaya a project.plist, luego agregue la orientación de la interfaz compatible y luego agregue solo Vertical (botón de inicio inferior) y Vertical (botón de inicio superior).
Puede agregar o eliminar la orientación según los requisitos de su proyecto.
Gracias
fuente
1) Verifique la configuración de su proyecto e info.plist y asegúrese de que solo estén seleccionadas las orientaciones que desea.
2) agregue los siguientes métodos a su controlador de vista superior (controlador de navegación / controlador de barra de pestañas)
- (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }
3) agregue los siguientes métodos al delegado de su aplicación
- (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return UIInterfaceOrientationMaskPortrait; }
fuente
Ponga esto en el archivo .m de cada
ViewController
uno que no quiera rotar:- (NSUInteger)supportedInterfaceOrientations { //return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft; return UIInterfaceOrientationMaskPortrait; }
Consulte aquí para obtener más información.
fuente