私のアプリ(iPad; iOS 6)は横長のみのアプリケーションですが、UIPopoverControllerを使用して写真ライブラリを表示しようとすると、次のエラーがスローされます:Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES.
veは運がなかった。
IOS6では、次の3つの場所でインターフェイスの方向をサポートしています。
このエラーが発生している場合、UIPopoverでロードしているビューはポートレートモードのみをサポートしているためです。これは、Game Center、iAd、または独自のビューが原因である可能性があります。
独自のビューの場合、UIViewControllerでsupportedInterfaceOrientationsをオーバーライドすることで修正できます。
- (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;
}
自分のビュー(iPhoneのGameCenterなど)ではない場合、.plistがポートレートモードをサポートしていることを確認する必要があります。また、UIApplicationDelegateがポートレートモードで表示されるビューをサポートしていることを確認する必要があります。これを行うには、.plistを編集してから、UIApplicationDelegateのsupportedInterfaceOrientationをオーバーライドします。
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
サブクラス化を避け、大量のコードを追加する方法を探すのに多くの時間を費やした後、ここに私の1行のコードソリューションがあります。
新しいUIImagePickerControllerのカテゴリを作成して追加します
-(BOOL)shouldAutorotate{
return NO;
}
それはすべての人々です!
このエラーメッセージが表示される別のケースがあります。問題が見つかるまで何時間も探していました。このスレッドは、数回読んだ後に非常に役に立ちました。
メインView Controllerを横向きに回転させ、縦向きで表示するカスタムSub View Controllerを呼び出すと、コードが次のようになったときにこのエラーメッセージが表示される可能性があります。
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationPortrait;
}
ここでの落とし穴は、Xcodeのインテリセンスが「UIInterfaceOrientationPortrait」を示唆したことであり、私はそれを気にしませんでした。一見、これは正しいように見えました。
右のマスクは
UIInterfaceOrientationMaskPortrait
小さな中置記号"マスク"に注意してください。そうしないと、サブビューが例外になり、上記のエラーメッセージが表示されます。
新しい列挙型はビットシフトされます。古い列挙型は無効な値を返します!
(UIApplication.hでは、新しい宣言を見ることができます:UIInterfaceOrientationMaskPortrait =(1 << UIInterfaceOrientationPortrait))
解決策は次のとおりです。
- (BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
// ATTENTION! Only return orientation MASK values
// return UIInterfaceOrientationPortrait;
return UIInterfaceOrientationMaskPortrait;
}
Swiftで使用
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
ランドスケープのみのアプリで画像ピッカーを表示するときに、同様の問題がありました。 Luiji博士が示唆したように、コントローラーの冒頭に次のカテゴリーを追加しました。
// 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
ViewController .mファイルの@implementationの直前にこれらの行を追加するのが最も簡単です。
コードで同じエラーメッセージが表示されました。私はこれを見つけました、それはアップルによって報告されたバグです:
https://devforums.Apple.com/message/731764#731764
彼の解決策は、AppDelegateで修正することです。私はそれを実装し、それは私のために働いています!
私は同じ問題を抱えていましたが、この答えは https://stackoverflow.com/a/12523916 でうまくいきます。よりエレガントなソリューションがあるかどうか疑問に思います。
私のコード:
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-UIModalPresentationPopoverを使用して、ハッキングなしでポップオーバーに表示できます。理想的ではありませんが、何よりも優れています。
imagePicker.modalPresentationStyle = UIModalPresentationPopover;
imagePicker.popoverPresentationController.sourceView = self.view;
imagePicker.popoverPresentationController.sourceRect = ((UIButton *)sender).frame;
編集:おそらく、異なるUIModalPresentationStylesを試してください-多分、ランドスケープで動作します。
- (BOOL)shouldAutorotate {
return NO;
}
-(NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
This removes the crash.
私の問題を解決した別のオプションは、UIImagePickerControllerのサブクラスを作成し、以下のメソッドをオーバーライドすることでした
@interface MyImagePickerController ()
@end
@implementation MyImagePickerController
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
UIImagePickerControllerの代わりにこれを使用すると、すべて正常に動作します。
このバグを修正するには、カテゴリを作成すると非常に役立ちます。そして、作成したカテゴリをインポートすることを忘れないでください。これにより、欠落しているメソッドがUIImagePickerControllerに追加され、iOS 6では、ドキュメントにbtwと記載されている場合にのみ、Portraitで機能するように制限されます。
他のソリューションが機能した可能性があります。しかし、iOS 6.1にデプロイするためにコンパイルされたiOS 8.xのSDKでは、これが道のりのようです。
。h-ファイル:
#import <UIKit/UIKit.h>
@interface UIImagePickerController (iOS6FIX)
- (BOOL) shouldAutorotate;
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation;
@end
。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)
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
}
}
あなたの答えもありがとう。作業済みのコードを切り取り、単純にリファクタリングしました。
Swift 4以降では、アプリ全体が横長であり、単一のコントローラーを縦長で表示する必要があると想定しています。ポートレートである必要があるView Controllerで、次を追加します。
override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .portrait
}
open override var shouldAutorotate: Bool {
return false
}
UIInterfaceOrientationPortrait
をUIInterfaceOrientationMaskPortrait
に暗黙的に変換するが戻り値としてこのクラッシュの問題に遭遇しました。
UIPageViewControllerDelegate
の詳細なコード背景、皆さんだけの参考にしてください。
-(UIInterfaceOrientationMask)pageViewControllerSupportedInterfaceOrientations:
(UIPageViewController *)pageViewController
{
# return UIInterfaceOrientationPortrait; # wrong
return UIInterfaceOrientationMaskPortrait; # correct
}