Antes do iOS 8, usamos o código abaixo em conjunto com os métodos de delegação supportedInterfaceOrientations e shouldAutoRotate para forçar a orientação do aplicativo a qualquer orientação específica. Usei o trecho de código abaixo para girar programaticamente o aplicativo para a orientação desejada. Em primeiro lugar, estou alterando a orientação da barra de status. E então, apenas apresentar e descartar imediatamente uma vista modal gira a vista para a orientação desejada.
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:YES];
UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:vc animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];
Mas isso está falhando no iOS 8. Além disso, tenho visto algumas respostas no estouro de pilha, nas quais as pessoas sugeriam que devemos sempre evitar essa abordagem a partir do iOS 8.
Para ser mais específico, meu aplicativo é um tipo universal de aplicativo. Existem três controladores no total.
Controlador First View - Ele deve suportar todas as orientações no iPad e apenas retrato (botão home para baixo) no iPhone.
Controlador Second View - Ele deve suportar apenas paisagem em todas as condições
Controlador Third View - ele deve suportar apenas paisagem em todas as condições
Estamos usando o controlador de navegação para navegação na página. No primeiro controlador de exibição, em uma ação de clique no botão, estamos pressionando o segundo na pilha. Portanto, quando o segundo controlador de exibição chegar, independentemente da orientação do dispositivo, o aplicativo deverá bloquear apenas a paisagem.
Abaixo estão meus métodos shouldAutorotate
e supportedInterfaceOrientations
no segundo e terceiro controlador de exibição.
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeRight;
}
-(BOOL)shouldAutorotate {
return NO;
}
Existe alguma solução para essa ou qualquer maneira melhor de bloquear um controlador de exibição em particular orientação para o iOS 8. Por favor, ajude !!
fonte
Respostas:
Para iOS 7 - 10:
Objetivo-C:
Swift 3:
Basta chamá-lo no
- viewDidAppear:
controlador de exibição apresentado.fonte
[UIView setAnimationsEnabled:NO];
emviewWillAppear
e[UIView setAnimationsEnabled:YES];
emviewDidAppear
, relacionado: stackoverflow.com/a/6292506/88597[UINavigationController attemptRotationToDeviceOrientation];
A rotação da orientação é um pouco mais complicada se você estiver dentro de um
UINavigationController
ouUITabBarController
. O problema é que, se um controlador de exibição estiver incorporado em um desses controladores, o controlador da barra de navegação ou de tabulação terá precedência e tomará decisões sobre autorotação e orientações suportadas.Eu uso as 2 extensões a seguir no UINavigationController e UITabBarController para que os controladores incorporados em um desses controladores tomem as decisões.
Dê aos controladores de exibição o poder!
Swift 2.3
Swift 3
Agora você pode substituir o
supportedInterfaceOrientations
método ou pode substituirshouldAutoRotate
no controlador de exibição que deseja bloquear, caso contrário, pode deixar de fora as substituições em outros controladores de exibição que deseja herdar o comportamento de orientação padrão especificado na lista de aplicativos do seu aplicativoDesativar rotação
Bloquear a orientação específica
Em teoria, isso deve funcionar para todas as hierarquias complexas de controladores de exibição, mas notei um problema com o UITabBarController. Por alguma razão, ele deseja usar um valor de orientação padrão. Consulte a seguinte postagem no blog se estiver interessado em aprender sobre como solucionar alguns dos problemas:
Bloquear rotação da tela
fonte
Isto é o que funcionou para mim:
https://developer.apple.com/library//ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/clm/UIViewController/attemptRotationToDeviceOrientation
Chame-o no seu método viewDidAppear:.
fonte
Descobri que se é um controlador de exibição apresentado, você pode substituir
preferredInterfaceOrientationForPresentation
Rápido:
fonte
Dessa forma, funciona para mim no Swift 2 iOS 8.x:
PS (esse método não requer que as funções de orientação sejam substituídas, como deve-se fazer a autenticação em todos os viewController, apenas um método no AppDelegate)
Marque a opção "requer tela cheia" no projeto de informações gerais.
Portanto, no AppDelegate.swift, faça uma variável:
Então, coloque também esta função:
Portanto, em todas as classes do seu projeto, você pode definir esse var em viewWillAppear:
Se você precisar fazer escolhas com base no tipo de dispositivo, faça o seguinte:
fonte
Primeiro de tudo - essa é uma péssima idéia, em geral, algo de errado com a arquitetura do seu aplicativo, mas,
sh..t happens
nesse caso, você pode tentar criar algo como abaixo:Do que, em
AppDelegate
E sempre que você quiser alterar a orientação, faça o seguinte:
Nota: Às vezes, o dispositivo pode não ser atualizado a partir dessa chamada, portanto, você pode fazer o seguinte
Isso é tudo
fonte
Isso deve funcionar no iOS 6 em diante, mas eu o testei apenas no iOS 8. Subclasse
UINavigationController
e substitua os seguintes métodos:Ou pergunte ao controlador de vista visível
e implementar os métodos lá.
fonte
Este é um feedback para os comentários na resposta de Sid Shah , sobre como desativar animações usando:
Código:
fonte
Se você estiver usando o navigationViewController, crie sua própria superclasse para isso e substitua:
isso desativará a rotação no SecondViewController, mas se você pressionar o SecondViewController quando o dispositivo estiver na orientação retrato, o SecondViewController aparecerá no modo retrato.
Suponha que você esteja usando o storyboard. Você precisa criar segue manual ( Como fazer ) e no seu método "onClick":
Isso forçará a orientação da paisagem antes que sua superclasse desative o recurso de rotação automática.
fonte
Nos
Xcode 8
métodos são convertidos em propriedades, portanto, o seguinte funciona comSwift
:fonte
portrait
modo, independentemente da orientação no iPad, com oshouldAutorotate
retorno verdadeiro, consegui isso.Eu tentei muitas soluções, mas a que funcionou é a seguinte:
Não é necessário editar o
info.plist
ios 8 e 9.Orientações possíveis da documentação da Apple :
fonte
A combinação das respostas de Sids e Koreys funcionou para mim.
Estendendo o Controlador de Navegação:
Desativando a rotação na única visualização
E girando para a orientação apropriada antes de seguir
fonte
A melhor solução acima:
não funcionou para mim quando o chamei em viewDidAppear do controlador de exibição apresentado. No entanto, funcionou quando o chamei em preparForSegue no controlador de exibição de apresentação.
(Desculpe, não há pontos de reputação suficientes para comentar sobre essa solução, então eu tive que adicioná-la assim)
fonte
[iOS9 +] Se alguém arrastou todo o caminho até aqui, como nenhuma das soluções acima funcionou, e se você apresentar a visualização, deseja alterar a orientação seguindo, você pode verificar isso.
Verifique o tipo de apresentação do seu segue. O meu estava "acima do contexto atual". Quando mudei para Fullscreen, funcionou.
Graças a @GabLeRoux, encontrei esta solução.
fonte
Meus requisitos são
AVPlayerViewController
para reproduzir vídeoQuando o vídeo estiver sendo reproduzido, se for uma paisagem, permita que a tela gire a paisagem para a direita e a paisagem para a esquerda. Se for um retrato, bloqueie a visualização apenas no modo retrato.
Primeiro, defina
supportedInterfaceOrientationsForWindow
emAppDelegate.swift
Segundo, no seu controlador de exibição principal, defina as seguintes funções
Então, você precisa subclassificar
AVPlayerViewController
Substitua essas três funções em
MyPlayerViewController.swift
Como o usuário pode girar a paisagem do dispositivo para a esquerda ou direita, precisamos definir a rotação automática para ser verdadeira
Por fim, crie uma
MyPlayerViewController
instância no seu controlador de exibição e defina o valor do tamanho da propriedade.Inicie o seu player com o apropriado
videoUrl
, depois atribua-o aplayerViewController
. Feliz codificação!fonte
fonte
Ainda parece haver algum debate sobre a melhor forma de realizar essa tarefa, então pensei em compartilhar minha abordagem (de trabalho). Adicione o seguinte código em sua
UIViewController
implementação:Neste exemplo, você também precisará definir as orientações permitidas do dispositivo para 'Paisagem à esquerda' nas configurações do seu projeto (ou diretamente
info.plist
). Apenas mude a orientação específica que você deseja forçar se quiser algo diferente deLandscapeLeft.
A chave para mim foi a
attemptRotationToDeviceOrientation
ligaçãoviewWillAppear
- sem que a visualização não girasse corretamente sem girar fisicamente o dispositivo.fonte
De acordo com a resposta de Korey Hinton
Swift 2.2:
Desativar rotação
Bloquear a orientação específica
fonte
Eu tentei algumas soluções aqui e o importante é entender que é o controlador de visualização raiz que determinará se ele irá girar ou não.
Criei o seguinte projeto objetivo-c github.com/GabLeRoux/RotationLockInTabbedViewChild com um exemplo de trabalho de
TabbedViewController
onde uma exibição filho é permitida girar e a outra exibição filho é bloqueada em retrato.Não é perfeito, mas funciona e a mesma ideia deve funcionar para outros tipos de visualizações raiz, como
NavigationViewController
. :)fonte
De acordo com a solução mostrada pelo @ sid-sha, você deve colocar tudo no
viewDidAppear:
método, caso contrário você não serádidRotateFromInterfaceOrientation:
acionado, então algo como:fonte
Minha solução
Em
AppDelegate
:XXViewController
é o ViewController que você deseja suportar no modo paisagem.Em seguida, a solução do Sunny Shah funcionaria no seu
XXViewController
em qualquer versão do iOS:Esta é a função de utilitário para encontrar o ViewController superior.
fonte
Use isso para bloquear a orientação do controlador de exibição, testado no IOS 9:
// Bloqueia a orientação para a paisagem direita
fonte
Eu tenho o mesmo problema e perco tanto tempo com isso. Então agora eu tenho minha solução. No entanto, algumas telas do meu aplicativo precisam ter apenas paisagem. Eu o corrigi com uma variável isShouldRotate no AppDelegate . E a função no AppDelegate :
E, finalmente, quando um ViewControllerA precisa de um estado de paisagem. Faça isso: antes de enviar / apresentar para o ViewControllerA atribuir isShouldRotate como true . Não se esqueça de quando pop / dispensar a atribuição do controlador isShouldRotate a false em viewWillDisappear .
fonte
Para mim, o VC de nível superior precisava implementar as substituições de orientação. Usar VCs na pilha não terá efeito se o VC superior não estiver implementando.
Apenas o VC-Main é ouvido, essencialmente nos meus testes.
fonte
Parece que mesmo aqui, há tantas respostas que ninguém foi suficiente para mim. Eu queria forçar a orientação e depois voltar para a orientação do dispositivo, mas
[UIViewController attemptRotationToDeviceOrientation];
simplesmente não funcionou. O que também complicou a coisa toda é que eu adicionei shouldAutorotate a false com base em alguma resposta e não consegui que os efeitos desejados retornassem corretamente em todos os cenários.Então foi isso que eu fiz:
Antes de pressionar o controlador na chamada em seu construtor init, isso:
Então, eu salvo a última orientação do dispositivo e me registro no evento de mudança de orientação. O evento de mudança de orientação é simples:
E, na visão dissimulante, apenas forço a retornar a qualquer orientação que eu tenha como userOreintation:
E isso tem que estar lá também:
E também o controlador de navegação deve delegar para shouldAutorotate e supportedInterfaceOrientations, mas acredito que a maioria das pessoas já possui.
PS: Desculpe, eu uso algumas extensões e classes base, mas os nomes são bastante significativos, então o conceito é compreensível, fará extensões ainda mais porque não é muito bonito agora.
fonte