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.

Destiny Dawn
fonte
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
Melhor resposta aqui stackoverflow.com/questions/20468335/…
Damien Romito

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;
}
Snickers
fonte
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!

Dr.Luiji
fonte
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)
}
JackPearse
fonte
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.

Trausti Kristjansson
fonte
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!

Robby
fonte
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];
Poetowen
fonte
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.

derbs
fonte
3
- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.
Suhail Bhat
fonte
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.

EquiAvia Tech
fonte
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
Helge Staedtler
fonte
1

Swift 3

let imagePicker = UIImagePickerController()

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

present(imagePicker, animated: true)
zumbi
fonte
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
}
Itachi
fonte
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.

Atereshkov
fonte
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
}
Gal Blank
fonte