Mon application (iPad; iOS 6) est une application uniquement en mode paysage, mais lorsque j'essaie d'utiliser un UIPopoverController pour afficher la photothèque, cette erreur renvoie cette erreur: Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES.
J'ai essayé de changer beaucoup de code mais je n'ai pas eu de chance.
Dans IOS6, vous avez pris en charge les orientations d'interface à trois endroits:
Si vous obtenez cette erreur, il est fort probable que la vue que vous chargez dans votre UIPopover ne prend en charge que le mode portrait. Cela peut être causé par Game Center, iAd ou votre propre vue.
S'il s'agit de votre propre vue, vous pouvez y remédier en remplaçant les interfaces supportedInterfaceOrientations sur votre 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;
}
S'il ne s'agit pas de votre propre vue (telle que GameCenter sur iPhone), vous devez vous assurer que votre .plist prend en charge le mode portrait. Vous devez également vous assurer que votre UIApplicationDelegate prend en charge les vues affichées en mode portrait. Vous pouvez le faire en modifiant votre nom de fichier .plist, puis en remplaçant le supportedInterfaceOrientation sur votre UIApplicationDelegate:
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
Après avoir passé beaucoup de temps à chercher un moyen d'éviter les sous-classes et d'ajouter une tonne de code, voici ma solution de code en une ligne.
Créez une nouvelle catégorie UIImagePickerController et ajoutez
-(BOOL)shouldAutorotate{
return NO;
}
C'est tout les gens!
Il y a un autre cas, ce message d'erreur peut apparaître. Je cherchais des heures jusqu'à ce que je trouve le problème. Ce fil a été très utile après l'avoir lu plusieurs fois.
Si votre contrôleur de vue principal est pivoté en orientation paysage et que vous appelez un contrôleur de vue secondaire personnalisé qui doit être affiché en orientation portrait, ce message d'erreur peut se produire lorsque votre code ressemble à ceci:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationPortrait;
}
Le piège ici était l'intellisense de xcode suggéré "UIInterfaceOrientationPortrait" et je m'en foutais. Au premier abord, cela semblait être correct.
Le bon masque est nommé
UIInterfaceOrientationMaskPortrait
Soyez conscient du petit infixe "Masque", sinon votre sous-vue se retrouvera avec une exception et le message d'erreur mentionné ci-dessus.
Les nouveaux enums sont un peu décalés. Les anciens enums renvoient des valeurs invalides!
(Dans UIApplication.h, vous pouvez voir la nouvelle déclaration: UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait) )
La solution est:
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
// ATTENTION! Only return orientation MASK values
// return UIInterfaceOrientationPortrait;
return UIInterfaceOrientationMaskPortrait;
}
Dans Swift utiliser
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
J'ai eu un problème similaire lors de la présentation du sélecteur d'images dans une application de type paysage uniquement. Comme suggéré par le Dr. Luiji, j'ai ajouté la catégorie suivante au début de mon contrôleur.
// 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
Il est plus facile d'ajouter ces lignes juste avant la @implémentation de votre fichier ViewController .m.
Je rencontrais le même message d'erreur dans mon code. J'ai trouvé ceci, c'est un bug rapporté par Apple:
https://devforums.Apple.com/message/731764#731764
Sa solution consiste à résoudre le problème dans AppDelegate. Je l'ai implémenté et ça marche pour moi!
J'ai eu le même problème et cette réponse https://stackoverflow.com/a/12523916 fonctionne pour moi. Je me demande s’il existe une solution plus élégante.
Mon code:
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];
iOS 8 - vous pouvez utiliser UIModalPresentationPopover sans aucun piratage à afficher dans une fenêtre popover. Pas idéal mais mieux que rien.
imagePicker.modalPresentationStyle = UIModalPresentationPopover;
imagePicker.popoverPresentationController.sourceView = self.view;
imagePicker.popoverPresentationController.sourceRect = ((UIButton *)sender).frame;
Edit: essayez peut-être les différents UIModalPresentationStyles - peut-être que plus fonctionnera dans le paysage.
- (BOOL)shouldAutorotate {
return NO;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
This removes the crash.
Une autre option qui a résolu mes problèmes a été de créer une sous-classe de UIImagePickerController et de remplacer la méthode ci-dessous.
@interface MyImagePickerController ()
@end
@implementation MyImagePickerController
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
Utilisez ceci à la place de UIImagePickerController et tout fonctionne bien.
Créer une catégorie est vraiment utile pour résoudre ce problème. Et n'oubliez pas d'importer votre catégorie créée. Cela ajoutera la méthode manquante à UIImagePickerController et, sur iOS 6, le restreindra à fonctionner dans Portrait uniquement, car la documentation indique btw.
Les autres solutions ont peut-être fonctionné. Mais avec SDK pour iOS 8.x compilé pour se déployer sur iOS 6.1, cela semble être la voie à suivre.
Le fichier .h:
#import <UIKit/UIKit.h>
@interface UIImagePickerController (iOS6FIX)
- (BOOL) shouldAutorotate;
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation;
@end
Le fichier .m:
#import "UIImagePickerController+iOS6FIX.h"
@implementation UIImagePickerController (iOS6FIX)
- (BOOL) shouldAutorotate {
return NO;
}
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
return UIInterfaceOrientationPortrait;
}
@end
Swift
let imagePicker = UIImagePickerController()
imagePicker.modalPresentationStyle = .popover
imagePicker.popoverPresentationController?.sourceView = sender // you can also pass any view
present(imagePicker, animated: true)
Je viens de résoudre le problème pour 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
}
}
Merci les gars pour vos réponses aussi. Je viens de couper le code travaillé et simplement le refactoriser.
Swift 4 et plus en supposant que toute l'application est en paysage et que vous devez présenter un seul contrôleur en portrait. Dans le contrôleur de vue devant être en mode portrait, ajoutez ce qui suit:
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
open override var shouldAutorotate: Bool {
return false
}
J'ai rencontré ce problème d'incident lorsque convertissant UIInterfaceOrientationPortrait
en UIInterfaceOrientationMaskPortrait
implicitement en tant que valeur de retour.
Plus d'informations sur le code sur UIPageViewControllerDelegate
, juste pour votre information.
-(UIInterfaceOrientationMask)pageViewControllerSupportedInterfaceOrientations:
(UIPageViewController *)pageViewController
{
# return UIInterfaceOrientationPortrait; # wrong
return UIInterfaceOrientationMaskPortrait; # correct
}