Como o ShouldAutorotateToInterfaceOrientation
está obsoleto no iOS 6 e usei-o para forçar uma determinada visualização para apenas retrato , qual é a maneira correta de fazer isso no iOS 6? Isso é apenas para uma área do meu aplicativo, todas as outras visualizações podem girar.
ios
xcode
ios6
xamarin.ios
Neal
fonte
fonte
A melhor maneira para iOS6 especificamente é observada em "iOS6 por Tutoriais" pela equipe de Ray Wenderlich - http://www.raywenderlich.com/ e é melhor do que criar subclasses
UINavigationController
na maioria dos casos.Estou usando o iOS6 com um storyboard que inclui um
UINavigationController
conjunto como controlador de visualização inicial.//AppDelegate.m - este método não está disponível pré-iOS6, infelizmente
- (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 - retorna as orientações que deseja suportar para cada
UIViewController
- (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; }
fonte
Esta resposta está relacionada às perguntas feitas nos comentários da postagem do OP:
Para forçar uma visualização a aparecer em uma determinada orientação, coloque o seguinte em viewWillAppear:
UIApplication* application = [UIApplication sharedApplication]; if (application.statusBarOrientation != UIInterfaceOrientationPortrait) { UIViewController *c = [[UIViewController alloc]init]; [self presentModalViewController:c animated:NO]; [self dismissModalViewControllerAnimated:NO]; }
É um pouco hack, mas isso força o
UIViewController
a ser apresentado em retrato, mesmo se o controlador anterior fosse paisagemATUALIZAÇÃO para iOS7
Os métodos acima agora estão obsoletos, portanto, para iOS 7, use o seguinte:
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, no momento da escrita, quer no presente ou descartar deve ser animada. Caso contrário, você receberá uma tela branca. Não tenho ideia de por que isso faz funcionar, mas funciona! O efeito visual é diferente dependendo de qual é animado.
fonte
Então, encontrei o mesmo problema ao exibir apenas visualizações modais de retrato. Normalmente, eu criaria um
UINavigationController
, definiriaviewController
como erootViewController
, em seguida, exibiria oUINavigationController
como uma visualização modal. Mas com o iOS 6, oviewController
irá agora pedir ao navigationController as orientações de interface suportadas (que, por padrão, agora é tudo para iPad e tudo menos de cabeça para baixo para iPhone).Solução : Tive que criar uma subclasse
UINavigationController
e substituir os métodos de auto-rotação. Meio coxo.- (BOOL)shouldAutorotate { return NO; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } // pre-iOS 6 support - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { return (toInterfaceOrientation == UIInterfaceOrientationPortrait); }
fonte
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; }
fonte
Eu discordo da resposta @aprato, porque os métodos de rotação UIViewController são declarados nas próprias categorias, resultando em um comportamento indefinido se você substituí-los em outra categoria. É mais seguro substituí-los em uma subclasse UINavigationController (ou UITabBarController)
Além disso, isso não cobre o cenário onde você empurra / apresenta / pop de uma visualização Paisagem para um retrato apenas VC ou vice-versa. Para resolver esse problema difícil (nunca abordado pela Apple), você deve:
No iOS <= 4 e iOS> = 6:
UIViewController *vc = [[UIViewController alloc]init]; [self presentModalViewController:vc animated:NO]; [self dismissModalViewControllerAnimated:NO]; [vc release];
No iOS 5:
UIWindow *window = [[UIApplication sharedApplication] keyWindow]; UIView *view = [window.subviews objectAtIndex:0]; [view removeFromSuperview]; [window addSubview:view];
Isso REALMENTE forçará o UIKit a reavaliar todas as suas shouldAutorotate, supportedInterfaceOrientations, etc.
fonte
Tenho uma abordagem muito boa misturando https://stackoverflow.com/a/13982508/2516436 e 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; } }
e retornar quaisquer orientações que você deseja oferecer suporte para cada UIViewController
- (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; }
fonte
Eu tenho um aplicativo universal relativamente complexo usando UISplitViewController e UISegmentedController, e tenho algumas visualizações que devem ser apresentadas em Paisagem usando
presentViewController
. Usando os métodos sugeridos acima, consegui fazer com que o iPhone ios 5 e 6 funcionasse de forma aceitável, mas por algum motivo o iPad simplesmente se recusou a apresentar como paisagem. Por fim, encontrei uma solução simples (implementada após horas de leitura e tentativa e erro) que funciona para dispositivos e iOS 5 e 6.Etapa 1) No controlador, especifique a orientação necessária (mais ou menos conforme observado acima)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return (interfaceOrientation == UIInterfaceOrientationLandscapeRight); } -(BOOL)shouldAutorotate { return YES; } -(NSUInteger)supportedInterfaceOrientations { NSInteger mask = UIInterfaceOrientationMaskLandscape; return mask; }
Etapa 2) Crie uma subclasse UINavigationController simples e implemente os seguintes métodos
-(BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; }
Etapa 3) Apresente seu viewController
vc = [[MyViewController alloc]init]; MyLandscapeNavigationController *myNavigationController = [[MyLandscapeNavigationController alloc] initWithRootViewController:vc]; [self myNavigationController animated:YES completion:nil];
Espero que isto seja útil para alguém.
fonte
Não quero ser chato aqui, mas você faria a gentileza de compartilhar sua subclasse? Obrigado.
editar: bem, eu finalmente consegui, a subclasse era muito simples de fazer. Eu apenas tive que declarar o
navigationController
in the asAppDelegate
emUINavigationControllerSubclass
vez do defaultUINavigationController
, então modifiquei sua subclasse com:- (BOOL)shouldAutorotate { return _shouldRotate; }
então posso definir qualquer visão que eu queira girar ou não ligando para
viewDidLoad
_navController = (UINavigationController *)self.navigationController; [_navController setShouldRotate : YES / NO]
Espero que este ajuste ajude outras pessoas também, obrigado pela sua dica!
Dica: Faça uso de
- (NSUInteger)supportedInterfaceOrientations
em seus controladores de visualização, para que você não termine tendo uma visualização desejada de retrato em paisagem ou vice-versa.
fonte
Eu não testei, mas a documentação afirma que agora você pode substituir esses métodos:
supportedInterfaceOrientations
epreferredInterfaceOrientationForPresentation
.Você provavelmente pode conseguir o que deseja definindo apenas a orientação que deseja nesses métodos.
fonte
As respostas usando subclasses ou categorias para permitir VCs dentro das classes UINavigationController e UITabBarController funcionam bem. Falha ao iniciar um modal somente retrato de um controlador de barra de guias em paisagem. Se você precisar fazer isso, use o truque de exibir e ocultar uma visualização modal não animada, mas faça isso no método viewDidAppear . Não funcionou para mim em viewDidLoad ou viewWillAppear.
Além disso, as soluções acima funcionam bem.
fonte
Para Monotouch, você pode fazer desta forma:
public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations() { return UIInterfaceOrientationMask.LandscapeRight; } public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation() { return UIInterfaceOrientation.LandscapeRight; }
fonte
Eu vejo muitas respostas, mas não entendo a ideia específica e a resposta sobre a orientação, mas vejo o link para entender bem a orientação e remover a rotação forçada para iOS6.
http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/
Eu acho que é ajuda completa.
fonte
Basta ir para project.plist e adicionar Orientação da interface compatível e adicionar apenas Retrato (botão home inferior) e Retrato (botão home superior).
Você pode adicionar ou remover a orientação de acordo com os requisitos do projeto.
obrigado
fonte
1) Verifique as configurações do projeto e info.plist e certifique-se de que apenas as orientações que você deseja estão selecionadas.
2) adicione os seguintes métodos ao seu controlador de visualização superior (controlador de navegação / controlador de barra de guias)
- (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; }
3) adicione os seguintes métodos ao delegado do seu aplicativo
- (NSUInteger) supportedInterfaceOrientations { return UIInterfaceOrientationMaskPortrait; } - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return UIInterfaceOrientationMaskPortrait; }
fonte
Coloque isso no arquivo .m de cada um que
ViewController
você não deseja girar:- (NSUInteger)supportedInterfaceOrientations { //return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft; return UIInterfaceOrientationMaskPortrait; }
Veja aqui para mais informações.
fonte