As orientações com suporte não têm uma orientação comum com o aplicativo, e se o Autootate estiver retornando SIM '


92

Meu aplicativo (iPad; iOS 6) é um aplicativo somente paisagem, mas quando tento usar um UIPopoverController para exibir a biblioteca de fotos, ocorre o seguinte erro: Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES.Tentei alterar muitos códigos, mas não tive sorte.


1
você deve aceitar uma resposta. há muitas pessoas para obter ajuda e para outras pessoas que têm o mesmo problema, ajuda quando você marca a resposta correta para o seu problema!
— brush51 01 de

1
Não! nenhuma solução funciona no iOS 7 :( (headbang)
— AsifHabib

Respostas:


94

No IOS6, você tem suporte para orientações de interface em três lugares:

  1. O .plist (ou tela de resumo do destino)
  2. Seu UIApplicationDelegate
  3. O UIViewController que está sendo exibido

Se você está recebendo este erro, é provável que a visualização que você está carregando no UIPopover só suporte o modo retrato. Isso pode ser causado pelo Game Center, iAd ou por sua própria visualização.

Se for sua própria visualização, você pode corrigi-lo substituindo supportedInterfaceOrientations em seu UIViewController:

- (NSUInteger) supportedInterfaceOrientations
{
     //Because your app is only landscape, your view controller for the view in your
     // popover needs to support only landscape
     return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

Se não for a sua própria visualização (como o GameCenter no iPhone), você precisa se certificar de que seu .plist suporta o modo retrato. Você também precisa se certificar de que seu UIApplicationDelegate suporta visualizações que são exibidas no modo retrato. Você pode fazer isso editando o seu .plist e, em seguida, substituindo o supportedInterfaceOrientation em seu UIApplicationDelegate:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

3
UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRighté UIInterfaceOrientationMaskAllButUpsideDown UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightigual aUIInterfaceOrientationMaskLandscape
— Valerii Pavlov

4
Ou apenas use UIInterfaceOrientationMaskAll.
— Mark Wang

Perfeito. Mesmo que um popover "somente retrato" funcione em paisagem, ele não pode apresentar um controlador de visualização somente paisagem modalmente.
— Neal Ehardt 01 de

Não! Solução não trabalhou no iOS 7 :(. Stackoverflow.com/questions/23005351/...
— AsifHabib

Funcionou no iOS 8. Porém, teve que adicionar suporte a retrato para plist. Obrigado.
— Yaroslav

65

Depois de gastar muito tempo procurando uma maneira de evitar subclasses e adicionar toneladas de código, aqui está minha solução de código de uma linha.

Crie uma nova categoria de UIImagePickerController e adicione

-(BOOL)shouldAutorotate{
    return NO;
}

Isso é tudo, pessoal!


1
Funcionou para mim também, não testei totalmente, mas parece funcionar até agora.
— migs647 de

2
Esta parece ser a melhor solução.
— Juliano de

2
Trabalho! Isso é ótimo e realmente me ajudou em uma pitada. Obrigado Dr Luiji !!
— suporte

1
Agradável. Funciona para mim no iOS 6. Você também pode tornar isso configurável na categoria para flexibilidade total.
— Jared Egan

3
não funciona no iOS7, o método de categoria nem mesmo é chamado (embora incluído no pch)
— Peter Lapisu

43

Há outro caso em que essa mensagem de erro pode aparecer. Fiquei procurando por horas até encontrar o problema. Este tópico foi muito útil depois de lê-lo algumas vezes.

Se o seu controlador de visualização principal for girado para a orientação paisagem e você invocar um controlador de visualização secundária personalizado que deve ser exibido na orientação retrato, essa mensagem de erro pode ocorrer quando seu código se parece com este:

- (NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationPortrait;
}

A armadilha aqui foi o intellisense do xcode sugerido "UIInterfaceOrientationPortrait" e eu não me importei com isso. À primeira vista, isso parecia correto.

A máscara certa é nomeada

UIInterfaceOrientationMaskPortrait

Esteja ciente do pequeno infixo "Máscara" , caso contrário, sua subvisão terminará com uma exceção e a mensagem de erro mencionada acima.

Os novos enums são um pouco alterados. Os enums antigos retornam valores inválidos!

(em UIApplication.h você pode ver a nova declaração: UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait) )

A solução é:

- (BOOL)shouldAutorotate {

    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {

    // ATTENTION! Only return orientation MASK values
    // return UIInterfaceOrientationPortrait;

    return UIInterfaceOrientationMaskPortrait;
} 

Em uso rápido

override func shouldAutorotate() -> Bool {

    return true
}

override func supportedInterfaceOrientations() -> Int {

    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

5
aconteceu comigo pelo mesmo motivo
— ChenXin

Eu gostaria que a apple apenas tivesse feito o tipo de retorno UIInterfaceOrientationMask para que seja um pouco mais óbvio o que precisa ser retornado.
— LightningStryk de

A resposta de Jackpearse parece correta. Mas quando você olha para info.plist, há UISupportedInterfaceOrientations com UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight. Sem MÁSCARA aqui
— onmyway133

1
@onmyway: Isso é verdade, os valores plist não mudaram. Na versão anterior do iOS, a Apple usava os valores de máscara "não" dentro do código. Isso é algo legado. Suponho que a apple esteja mudando um pouco os valores plist internamente agora.
— JackPearse

Meu aplicativo costumava funcionar sem esse problema de travamento em um simulador de iPad do Xcode 6.2. E ele travou depois que eu atualizei para o Xcode 6.3 alguns dias atrás. Agora, essa solução resolve meu problema. Muito obrigado :-)
— Golden Thumb

22

Tive um problema semelhante ao apresentar o seletor de imagens em um aplicativo somente paisagem. Conforme sugerido pelo Dr. Luiji, adicionei a seguinte categoria no início do meu controlador.

// This category (i.e. class extension) is a workaround to get the
// Image PickerController to appear in landscape mode.
@interface UIImagePickerController(Nonrotating)
- (BOOL)shouldAutorotate;
@end

@implementation UIImagePickerController(Nonrotating)

- (BOOL)shouldAutorotate {
  return NO;
}
@end

É mais fácil adicionar essas linhas antes da implementação @ do seu arquivo ViewController .m.


Eu tenho um aplicativo apenas para retratos! e eu quero mostrar a câmera no modo paisagem. qualquer solução?????
— AsifHabib de

Trausti não funcionou? Eu tenho o mesmo problema e tentei seu código, mas ainda aparece a mesma exceção *** Encerrando o aplicativo devido à exceção não detectada 'UIApplicationInvalidInterfaceOrientation', motivo: 'Orientações suportadas não tem orientação comum com o aplicativo e deveriaAutorotate está retornando SIM ..... ... eu também coloquei um ponto de interrupção no método de categoria UIimagePickerView shouldAutorotate alcançando lá e retorna não, mas ainda assim fornecer esta exceção ... Meu aplicativo é apenas paisagem ... por favor me ajude
— Vishal16 01 de

Também funciona para forçar o SKStoreProductViewController a apresentar em retrato quando todo o aplicativo estiver em paisagem no iOS 8. Agradecendo a você.
— Yaroslav

11

Eu estava encontrando a mesma mensagem de erro em meu código. Eu encontrei isso, é um bug relatado pela Apple:

https://devforums.apple.com/message/731764#731764

Sua solução é consertá-lo no AppDelegate. Eu implementei e funciona para mim!


A propósito, originalmente encontrei isso em: stackoverflow.com/questions/12522491/…
— Robby

Essa foi a resposta certa, direto da Apple, e então eu só tive que seguir as mesmas instruções, mas fazê-lo em Swift para um aplicativo voltado para iOS 8. Tudo funciona muito bem. AppDelegate define supportedInterfaceOrientationsForWindow para Paisagem e Retrato, cada conjunto de arquivos swift individual substitui func supportedInterfaceOrientations para Paisagem apenas para que a exibição não gire, mas quando uma exibição de retrato (no meu caso SKStoreProductViewController) precisa carregar, funciona!
— RanLearns

Caramba, existem tantas soluções sugeridas, e esta de longe não tem os pontos mais altos, mas é de fato a correta. Testado em iOS 10 e 9. Nada mais funciona.
— Demian Turner

6

Eu tive o mesmo problema e esta resposta https://stackoverflow.com/a/12523916 funciona para mim. Gostaria de saber se existe uma solução mais elegante.

Meu código:

UIImagePickerController  *imagePickerController = [[NonRotatingUIImagePickerController alloc] init];
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;

UIPopoverController  *popoverVC = [[UIPopoverController alloc] initWithContentViewController:imagePickerController];    

[popoverVC presentPopoverFromRect:frame   // did you forget to call this method?
                           inView:view
         permittedArrowDirections:UIPopoverArrowDirectionAny
                         animated:YES];

Tentei fazer isso, mas quando clico no botão para chamar o código, mas nada é exibido, também tentei adicionar @interface NonRotatingUIImagePickerController : UIImagePickerController @end @implementation NonRotatingUIImagePickerController - (BOOL)shouldAutorotate { return NO; } @endao código, mas meu código não detectou NonRotatingUIImagePickerController.
— Destiny Dawn,

1
Não se preocupe, ele detecta NonRotatingUIImagePickerController agora, mas nada ainda é exibido ... @poetowen
— Destiny Dawn

4

iOS 8 - você pode usar UIModalPresentationPopover sem quaisquer hacks para exibir em um popover. Não é ideal, mas é melhor do que nada.

imagePicker.modalPresentationStyle = UIModalPresentationPopover;
imagePicker.popoverPresentationController.sourceView = self.view;
imagePicker.popoverPresentationController.sourceRect = ((UIButton *)sender).frame;

Editar: talvez tente os diferentes UIModalPresentationStyles - talvez mais funcionem na paisagem.


3
- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.

2

Outra opção que resolveu meus problemas foi criar uma subclasse do UIImagePickerController e substituir o método abaixo

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

Use-o em vez do UIImagePickerController e tudo funcionará bem.


1

Criar uma categoria é muito útil para corrigir esse bug. E não se esqueça de importar sua categoria criada. Isso adicionará o método ausente ao UIImagePickerController e no iOS 6 irá restringi-lo para funcionar no Portrait apenas como a documentação afirma btw.

As outras soluções podem ter funcionado. Mas com o SDK para iOS 8.x compilado para implantação no iOS 6.1, esse parece o caminho a percorrer.

O arquivo .h:

#import <UIKit/UIKit.h>

@interface UIImagePickerController (iOS6FIX)

- (BOOL) shouldAutorotate;
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation;

@end

O arquivo .m:

#import "UIImagePickerController+iOS6FIX.h"

@implementation UIImagePickerController (iOS6FIX)

- (BOOL) shouldAutorotate {
    return NO;
}

- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}

@end

1

Swift 3

let imagePicker = UIImagePickerController()

imagePicker.modalPresentationStyle = .popover
imagePicker.popoverPresentationController?.sourceView = sender // you can also pass any view 

present(imagePicker, animated: true)

0

Encontrei esse problema de travamento ao converter UIInterfaceOrientationPortraitpara UIInterfaceOrientationMaskPortraitimplicitamente como um valor de retorno.

Mais informações sobre o código UIPageViewControllerDelegate, apenas para sua informação.

 -(UIInterfaceOrientationMask)pageViewControllerSupportedInterfaceOrientations:
(UIPageViewController *)pageViewController
{
    # return UIInterfaceOrientationPortrait;    # wrong
    return UIInterfaceOrientationMaskPortrait;  # correct
}

0

Acabei de resolver o problema do Swift 4.x

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    configureVideoOrientation()
}

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransition(to: size, with: coordinator)
    coordinator.animate(alongsideTransition: nil, completion: { [weak self] _ in
        self?.configureVideoOrientation()
    })
}

private func configureVideoOrientation() {
    guard let previewLayer = self.previewLayer, let connection = previewLayer.connection else { return }
    if connection.isVideoOrientationSupported {
        let orientation = UIApplication.shared.statusBarOrientation
        switch (orientation) {
        case .portrait:
            previewLayer.connection?.videoOrientation = .portrait
        case .landscapeRight:
            previewLayer.connection?.videoOrientation = .landscapeRight
        case .landscapeLeft:
            previewLayer.connection?.videoOrientation = .landscapeLeft
        case .portraitUpsideDown:
            previewLayer.connection?.videoOrientation = .portraitUpsideDown
        default:
            previewLayer.connection?.videoOrientation = .portrait
        }

        previewLayer.frame = self.view.bounds
    }
}

Obrigado pessoal por suas respostas também. Acabei de cortar o código trabalhado e simplesmente refatorá-lo.


0

Swift 4 e superior, assumindo que todo o aplicativo está em paisagem e você precisa apresentar um único controlador em retrato. No controlador de visualização que deve ser retrato, adicione o seguinte:

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

open override var shouldAutorotate: Bool {
    return false
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.