Tenho um aplicativo para iPhone que usa um UINavigationController
para apresentar uma interface detalhada: primeiro uma visualização, depois outra, até quatro níveis de profundidade. Quero as três primeiras visualizações restritas à orientação retrato e somente a última visualização deve ser permitida a girar para paisagem. Ao retornar da quarta visualização para a terceira e a quarta visualização estava na orientação paisagem, quero que tudo gire de volta para o retrato.
No iOS 5, eu simplesmente defini shouldAutorotateToInterfaceOrientation:
em cada um dos meus controladores de visualização para retornar SIM para as orientações permitidas. Tudo funcionou conforme descrito acima, incluindo o retorno ao retrato, mesmo se o dispositivo estivesse sendo mantido na orientação paisagem ao retornar do controlador de visualização nº 4 para o nº 3.
No iOS 6, todos os controladores de visualização giram para paisagem, interrompendo aqueles que não foram feitos para isso. As notas de lançamento do iOS 6 dizem
Mais responsabilidade é passar para o aplicativo e o delegado do aplicativo. Agora, os contêineres iOS (como
UINavigationController
) não consultam seus filhos para determinar se eles devem girar automaticamente. [...] O sistema pergunta ao controlador de exibição de tela inteira superior (normalmente o controlador de exibição raiz) para as orientações de interface suportadas sempre que o dispositivo gira ou sempre que um controlador de exibição é apresentado com o estilo de apresentação modal de tela inteira. Além disso, as orientações suportadas são recuperadas apenas se este controlador de visualização retornar YES de seushouldAutorotate
método. [...] O sistema determina se uma orientação é suportada pela intersecção do valor retornado pelosupportedInterfaceOrientationsForWindow:
método do aplicativo com o valor retornado pelosupportedInterfaceOrientations
método do controlador de tela inteira superior.
Então eu criei uma subclasse UINavigationController
, dei minha MainNavigationController
propriedade booleana landscapeOK
e usei isso para retornar as orientações permitidas em supportedInterfaceOrientations
. Então, em cada um dos viewWillAppear:
métodos dos meus controladores de visualização, eu tenho uma linha como esta
[(MainNavigationController*)[self navigationController] setLandscapeOK:YES];
para dizer ao meu MainNavigationController
o comportamento desejado.
Aí vem a pergunta: se eu agora navegar para a minha quarta visualização no modo retrato e virar o telefone, ele gira para a paisagem. Agora, pressiono o botão Voltar para retornar à minha terceira visualização, que deve funcionar apenas como retrato. Mas não gira de volta. Como faço isso?
eu tentei
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]
no viewWillAppear
método do meu terceiro controlador de visualização, mas não faz nada. Este é o método errado para chamar ou talvez o lugar errado para chamá-lo ou devo implementar tudo de uma maneira totalmente diferente?
fonte
Adicionar um CustomNavigationController
Substitua esses métodos nele:
Agora adicione todas as orientações no plist
No controlador de visualização, adicione apenas os necessários:
esses métodos substituem os métodos do controlador de navegação
fonte
ViewController
estejam no modo Retrato e o meuViewController
esteja no modo Paisagem e Retrato. Eu também dou suporte no iOS 5.0 e iOS 6.0. É por isso que estou confuso para contornar, mas esta é uma ótima solução. adiciono CustomNavigationController em meu controlador de exibição de raiz e dou suporte de acordo com minhas necessidades. Obrigado mais uma vez.Depois de examinar todas as respostas em inúmeras perguntas semelhantes no SO, nenhuma das respostas funcionou para mim, mas eles me deram algumas ideias. Veja como acabei resolvendo o problema:
Primeiro, certifique-se de que as Orientações de interface suportadas no destino do projeto contenham todas as orientações que você deseja para a vista rotativa.
Em seguida, crie uma categoria de
UINavigationController
(já que a Apple diz para não criar uma subclasse):Importe essa categoria e o controlador de visualização que você deseja que seja capaz de girar (que chamarei
RotatingViewController
) para seu controlador de visualização de nível mais alto, que deve conter seu controlador de navegação. Nesse controlador de visualização, implemente dashouldAutorotate
seguinte forma. Observe que este não deve ser o mesmo controlador de visualização que você deseja girar.Finalmente, em seu
RotatingViewController
, implementeshouldAutorotate
e dasupportedInterfaceOrientations
seguinte forma:O motivo pelo qual você precisa fazer isso é porque o iOS 6 dá o controle de rotação ao controlador de visualização raiz em vez do controlador de visualização superior. Se você deseja que a rotação de uma visão individual se comporte de maneira diferente de outras visões na pilha, você precisa escrever um caso específico para ela no controlador de visão raiz.
fonte
Não tenho reputação suficiente para comentar a resposta de @Brian, então acrescentarei minha observação aqui.
Brian mencionou que o iOS6 fornece o controle de rotação para o rootViewController - ele pode não ser apenas um UINavigationController como mencionado, mas também um UITabBarController, que era para mim. Minha estrutura é assim:
Então, adicionei os métodos primeiro em um UITabBarController personalizado, depois em um UINavigationController personalizado e, por último, no UIViewController específico.
Exemplo de UITabBarController e UINavigationController:
fonte
Eu gostaria de dar uma resposta parcial à minha própria pergunta. Achei a seguinte linha de código, usada no
viewWillAppear
método do meu terceiroUIViewController
, para funcionar:Mas eu realmente não gosto dessa solução. Ele está usando um truque para atribuir a uma propriedade somente leitura que, de acordo com a documentação da Apple, representa a orientação física do dispositivo. É como dizer ao iPhone para pular para a orientação correta na mão do usuário.
Estou muito tentado a deixar isso em meu aplicativo, pois simplesmente funciona. Mas não parece certo, então gostaria de deixar a questão em aberto para uma solução limpa.
fonte
Estou usando isso como suporte de orientação no ios 6.0
fonte
Sendo que este é um tópico muito visto. Pensei em acrescentar o que acredito ser a resposta mais fácil. Isso funciona para ios8 e superior
e
É isso aí. Aproveitar!
Ah, e meus ViewControllers estão embutidos em um controlador de navegação, que eu não precisei criar uma subclasse ou configurar de forma alguma.
fonte
Isso pode não funcionar para todos, mas funciona muito bem para mim. Em vez de implementar ...
em viewWillAppear em todos os meus controladores, decidi centralizar esse processo dentro da minha subclasse UINavigationController substituindo o método UINavigationControllerDelegate
navigationController:willShowViewController:animated:
Descobri que esse método delegado não é chamado ao retirar um VC da pilha de navegação. Isso não foi um problema para mim, porque estou lidando com a funcionalidade de retorno de dentro da minha subclasse UINavigationController para que eu possa definir os botões da barra de navegação adequados e ações para VCs específicos como este ...
Aqui está como o meu
back
método se parece para lidar com a retirada do VC da pilha e definir a preferência de rotação apropriada ...Então, como você pode ver, basicamente tudo o que está acontecendo é que primeiro estou definindo duas propriedades ...
no
navigationController:willShowViewController:animated:
qual irá determinar quais são as orientações suportadas dentro daquele VC que está para ser apresentado. Ao abrir um VC, meu método "back" personalizado está sendo chamado e, em seguida, estou configurando isLandscapeOK para o que foi armazenado por meio do valor previousVCLandscapeOK.Como eu disse, isso pode não funcionar para todos, mas funciona muito bem para mim e não tenho que me preocupar em adicionar código a cada um dos meus controladores de visualização, consegui manter tudo centralizado na subclasse UINavigationController.
Espero que isso ajude alguém como me ajudou. Obrigado, Jeremy.
fonte
Vá para o arquivo Info.plist e faça a alteração
fonte
Você deseja forçar o retrato do aplicativo iOS 6 somente então você pode adicionar a uma subclasse UIViewController métodos abaixo
fonte
NSUInteger
lança um aviso, apesar de ser o tipo var correto. se você tiver TOC, useUIInterfaceOrientationMask
.Eu queria ter todos os meus VCs bloqueados na orientação retrato, exceto um. Isto é o que funcionou para mim.
No controlador de visualização raiz, detecte o tipo de controlador de visualização que está na parte superior da janela e defina a orientação do aplicativo de acordo com o método supportedInterfaceOrientations . Por exemplo, eu precisava que meu aplicativo girasse apenas quando o webview estivesse no topo da pilha. Aqui está o que adicionei em meu rootVC:
fonte
[[Utils getAppDelegate] appNavigationController]
. Suponho que utils seja alguma aula que você tenha, mas não sei o que você faz nela. Qualquer ajuda seria ótimo!Não tenho reputação suficiente para responder à pergunta de @Ram S em @micmdk reply, portanto, adicionarei minha observação aqui.
Quando você usa UITabbarController , tente alterar self.viewControllers.lastObject no código de @ micmdk para self.selectedViewController assim:
fonte
Você pode implementar e substituir shouldAutorotate () e supportedInterfaceOrientations var em todas as classes do View Controller que devem ser apresentadas em orientações diferentes daquelas definidas na PLIST do seu aplicativo.
No entanto, em uma interface de usuário não trivial, você pode enfrentar um problema para adicioná-la em dezenas de classes e não quer torná-las subclasses de várias que a suportam (MyBaseTableViewController, MyBaseNavigationController e MyBaseTabBarController).
Uma vez que você não pode sobrescrever esses métodos / var em UIViewController diretamente, você pode fazer isso em suas subclasses que são normalmente classes básicas suas, como UITableViewController, UINavigationController e UITabBarController.
Portanto, você pode implementar algumas extensões e ainda configurar MyPreciousViewController para mostrar em orientações diferentes de todos os outros, como este snippet de código do Swift 4:
fonte
Eu resolvi o mesmo tipo de problema.
Se você estiver usando
UINavigationController
para enviar os controladores de visualização, você deve definir os métodos abaixo.No local de
LoginViewController
uso queUIViewController
você deseja mostrar. No meu caso, quero mostrarLoginViewController
noPortrait
modo outroViewControllers
nolandscape
modo.fonte
Use o seguinte método para resolver este problema
retorne apenas a orientação que desejar !!!
fonte