Gli orientamenti supportati non hanno un orientamento comune con l'applicazione e shouldAutorotate restituisce YES '


92

La mia app (iPad; iOS 6) è un'applicazione solo per il paesaggio, ma quando provo a utilizzare un UIPopoverController per visualizzare la libreria di foto, genera questo errore: Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES.ho provato a cambiare molto codice in giro ma non ho avuto fortuna.


1
dovresti accettare una risposta. ci sono molte persone che chiedono aiuto e per altre persone che hanno lo stesso problema aiuta quando contrassegni la risposta corretta per il tuo problema!
brush51

1
No! nessuna soluzione funziona su iOS 7 :( (headbang)
AsifHabib

Risposte:


94

In IOS6 hai supportato gli orientamenti dell'interfaccia in tre posizioni:

  1. Il .plist (o schermata di riepilogo del target)
  2. Your UIApplicationDelegate
  3. Il UIViewController che viene visualizzato

Se ricevi questo errore, è molto probabile che la visualizzazione che stai caricando nel tuo UIPopover supporta solo la modalità verticale. Ciò può essere causato da Game Center, iAd o dalla tua visualizzazione.

Se è la tua visualizzazione, puoi risolverlo sovrascrivendo supportedInterfaceOrientations sul tuo 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 non è la tua visualizzazione (come GameCenter su iPhone), devi assicurarti che il tuo .plist supporti la modalità verticale. È inoltre necessario assicurarsi che UIApplicationDelegate supporti le visualizzazioni visualizzate in modalità verticale. Puoi farlo modificando il tuo .plist e quindi sovrascrivendo SupportInterfaceOrientation su UIApplicationDelegate:

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

3
UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightuguale a UIInterfaceOrientationMaskAllButUpsideDown UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightugualeUIInterfaceOrientationMaskLandscape
Valerii Pavlov

4
O semplicemente usa UIInterfaceOrientationMaskAll.
Mark Wang

Perfetto. Anche se un popover "solo verticale" funzionerà in orizzontale, non può presentare modalmente un controller di visualizzazione solo orizzontale.
Neal Ehardt

No! Soluzione non ha lavorato su iOS 7 :(. Stackoverflow.com/questions/23005351/...
AsifHabib

Funzionava su iOS 8. Tuttavia, ho dovuto aggiungere il supporto per il ritratto a plist. Grazie.
Yaroslav

65

Dopo aver passato molto tempo a cercare un modo per evitare la sottoclasse e l'aggiunta di tonnellate di codice, ecco la mia soluzione di codice a una riga.

Creane una nuova categoria di UIImagePickerController e aggiungi

-(BOOL)shouldAutorotate{
    return NO;
}

È tutto gente!


1
Ha funzionato anche per me, non è stato completamente testato ma finora sembra funzionare.
migs647

2
Questa sembra essere la soluzione migliore.
Julian

2
Lavori! È fantastico e mi ha davvero aiutato in un attimo. Grazie Dr Luiji !!
parentesi

1
Bello. Per me funziona su iOS 6. Puoi anche renderlo configurabile nella categoria per la massima flessibilità.
Jared Egan

3
non funziona in iOS7, il metodo della categoria non viene nemmeno chiamato (sebbene incluso nel pch)
Peter Lapisu

43

C'è un altro caso in cui potrebbe apparire questo messaggio di errore. Ho cercato per ore finché non ho trovato il problema. Questo thread è stato molto utile dopo averlo letto un paio di volte.

Se il controller della vista principale viene ruotato in orientamento orizzontale e si richiama un controller della vista secondaria personalizzato che dovrebbe essere visualizzato in orientamento verticale, questo messaggio di errore può verificarsi quando il codice ha questo aspetto:

- (NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationPortrait;
}

La trappola qui era l'intellisense di xcode suggerito "UIInterfaceOrientationPortrait" e non mi importava. A prima vista questo sembrava essere corretto.

La maschera giusta è denominata

UIInterfaceOrientationMaskPortrait

Fai attenzione al piccolo infisso "Maschera" , altrimenti la tua sottoview finirà con un'eccezione e il messaggio di errore menzionato sopra.

Le nuove enumerazioni sono leggermente spostate. Le vecchie enumerazioni restituiscono valori non validi!

(in UIApplication.h puoi vedere la nuova dichiarazione: UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait) )

La soluzione è:

- (BOOL)shouldAutorotate {

    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {

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

    return UIInterfaceOrientationMaskPortrait;
} 

In rapido utilizzo

override func shouldAutorotate() -> Bool {

    return true
}

override func supportedInterfaceOrientations() -> Int {

    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

5
è successo a me per lo stesso motivo
ChenXin

Vorrei che Apple avesse semplicemente reso il tipo di ritorno UIInterfaceOrientationMask in modo che fosse un po 'più ovvio ciò che deve essere restituito.
LightningStryk

La risposta di Jackpearse sembra corretta. Ma quando guardi in info.plist, c'è UISupportedInterfaceOrientations con UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight. Nessuna MASCHERA qui
onmyway133

1
@onmyway: è vero, i valori plist non sono cambiati. Nella versione iOS precedente, Apple utilizzava i valori di maschera "non" all'interno del codice. Questa è roba ereditata. Presumo che Apple stia spostando i valori di plist internamente ora.
JackPearse

La mia app funzionava senza questo problema di arresto anomalo su un simulatore iPad di Xcode 6.2. Ed è andato in crash dopo che ho aggiornato a Xcode 6.3 pochi giorni fa. Ora questa soluzione risolve il mio problema. Grazie mille :-)
Golden Thumb

22

Ho riscontrato un problema simile durante la presentazione del selettore di immagini in un'app solo orizzontale. Come suggerito dal Dr. Luiji, ho aggiunto la seguente categoria all'inizio del mio controller.

// 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

È più semplice aggiungere queste righe appena prima dell'implementazione del file .m di ViewController.


Ho un'app solo per ritratti! e voglio mostrare Fotocamera in modalità Paesaggio. qualsiasi soluzione ?????
AsifHabib

Trausti non ha funzionato? Ho lo stesso problema e ho provato il tuo codice ma appare ancora la stessa eccezione *** Chiusura dell'app a causa di un'eccezione non rilevata "UIApplicationInvalidInterfaceOrientation", motivo: "Gli orientamenti supportati non hanno un orientamento comune con l'applicazione e shouldAutorotate sta restituendo SÌ ..... ... ho anche inserito un punto di interruzione sul metodo della categoria UIimagePickerView shouldAutorotate raggiungendo lì e restituisce no ma continua a dare questa eccezione ... La mia app è solo
orizzontale

Funziona anche per forzare SKStoreProductViewController a presentare in verticale quando l'intera app è in orizzontale in iOS 8. Grazie.
Yaroslav

11

Ho riscontrato lo stesso messaggio di errore nel mio codice. Ho trovato questo, è un bug come riportato da Apple:

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

La sua soluzione è risolverlo in AppDelegate. L'ho implementato e funziona per me!


A proposito, originariamente l'ho trovato su: stackoverflow.com/questions/12522491/…
Robby,

Questa è stata la risposta giusta, direttamente da Apple, quindi ho dovuto seguire le stesse istruzioni ma farlo in Swift per un'app destinata a iOS 8. Tutto funziona alla grande. AppDelegate imposta supportedInterfaceOrientationsForWindow sia su Landscape che su Portrait, ogni singolo file swift imposta override func supportedInterfaceOrientations su Landscape solo in modo che la vista non ruoti, ma quando una vista verticale (nel mio caso SKStoreProductViewController) deve essere caricata, funziona!
RanLearns

Accidenti, ci sono così tante soluzioni suggerite, e questa di gran lunga non ha i punti più alti, ma è davvero quella corretta. Testato su iOS 10 e 9. Nient'altro funziona.
Demian Turner

6

Ho avuto lo stesso problema e questa risposta https://stackoverflow.com/a/12523916 funziona per me. Chissà se esiste una soluzione più elegante.

Il mio codice:

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];

Ho provato a farlo, ma quando faccio clic sul pulsante per chiamare il codice ma non viene visualizzato nulla, ho anche provato ad aggiungere @interface NonRotatingUIImagePickerController : UIImagePickerController @end @implementation NonRotatingUIImagePickerController - (BOOL)shouldAutorotate { return NO; } @endal codice ma il mio codice non rilevava NonRotatingUIImagePickerController.
Destiny Dawn

1
Non importa, rileva NonRotatingUIImagePickerController ora ma non viene ancora visualizzato nulla ... @poetowen
Destiny Dawn

4

iOS 8: puoi utilizzare UIModalPresentationPopover senza alcun hack da visualizzare in un popover. Non ideale ma meglio di niente.

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

Modifica: forse prova i diversi UIModalPresentationStyles - forse più funzioneranno in orizzontale.


3
- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.

2

Un'altra opzione che ha risolto i miei problemi era creare una sottoclasse di UIImagePickerController e sovrascrivere il metodo seguente

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

Usa questo al posto di UIImagePickerController e tutto funziona correttamente.


1

La creazione di una categoria è davvero utile per correggere questo bug. E non dimenticare di importare la categoria creata. Questo aggiungerà il metodo mancante a UIImagePickerController e su iOS 6 lo limiterà a funzionare solo in verticale come afferma la documentazione btw.

Le altre soluzioni potrebbero aver funzionato. Ma con SDK per iOS 8.x compilato per la distribuzione su iOS 6.1 questa sembra la strada da percorrere.

Il file .h:

#import <UIKit/UIKit.h>

@interface UIImagePickerController (iOS6FIX)

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

@end

Il file .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

Ho riscontrato questo problema di arresto anomalo durante la conversione UIInterfaceOrientationPortraitin UIInterfaceOrientationMaskPortraitimplicitamente come valore di ritorno.

Ulteriori informazioni sullo sfondo del codice UIPageViewControllerDelegate, solo FYI per tutti voi.

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

0

Ho appena risolto il problema per 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
    }
}

Grazie ragazzi anche per le vostre risposte. Ho appena tagliato il codice funzionante e semplicemente rifattorizzato.


0

Swift 4 e versioni successive supponendo che l'intera app sia in orizzontale e devi presentare un singolo controller in verticale. Nel controller della vista che deve essere verticale aggiungere quanto segue:

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

open override var shouldAutorotate: Bool {
    return false
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.