95

我的应用程序(iPad;iOS 6)是一个仅限横向的应用程序,但是当我尝试使用 UIPopoverController 显示照片库时,它会抛出此错误: Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES.我尝试更改很多代码,但我没有运气。

4

14 回答 14

97

在 IOS6 中,您在三个地方支持界面方向:

  1. .plist(或目标摘要屏幕)
  2. 你的 UIApplicationDelegate
  3. 正在显示的 UIViewController

如果您收到此错误,很可能是因为您在 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;
}
于 2012-09-24T23:29:33.053 回答
66

在花费大量时间寻找避免子类化和添加大量代码的方法之后,这是我的单行代码解决方案。

新建一个 UIImagePickerController 的类别并添加

-(BOOL)shouldAutorotate{
    return NO;
}

这就是所有的人!

于 2012-10-11T07:28:58.070 回答
43

在另一种情况下,可能会出现此错误消息。我找了好几个小时才发现问题。这篇文章在阅读了几次之后非常有帮助。

如果您的主视图控制器旋转到横向并且您调用了一个应该以纵向显示的自定义子视图控制器,则当您的代码如下所示时可能会出现此错误消息:

- (NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationPortrait;
}

这里的陷阱是 xcode 的智能感知建议“UIInterfaceOrientationPortrait”,我不在乎。乍一看,这似乎是正确的。

正确的面具被命名

UIInterfaceOrientationMaskPortrait

请注意小中缀"Mask",否则您的子视图将最终出现异常和上面提到的错误消息。

新的枚举被移位。旧枚举返回无效值!

(在 UIApplication.h 你可以看到新的声明:UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait)

解决方案是:

- (BOOL)shouldAutorotate {

    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {

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

    return UIInterfaceOrientationMaskPortrait;
} 

迅速使用

override func shouldAutorotate() -> Bool {

    return true
}

override func supportedInterfaceOrientations() -> Int {

    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
于 2013-02-01T10:25:41.853 回答
22

在仅横向应用程序中显示图像选择器时,我遇到了类似的问题。根据 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 之前添加这些行是最简单的。

于 2012-11-12T17:30:31.407 回答
11

我在我的代码中遇到了相同的错误消息。我发现了这个,这是 Apple 报告的一个错误:

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

他的解决方案是在 AppDelegate 中修复它。我实现了它,它对我有用!

于 2013-01-22T23:37:35.077 回答
6

我遇到了同样的问题,这个答案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];
于 2012-09-22T18:02:11.683 回答
4
- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.
于 2014-01-16T05:27:42.953 回答
4

iOS 8 - 您可以使用 UIModalPresentationPopover 而无需任何技巧即可在弹出窗口中显示。不理想但总比没有好。

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

编辑:也许尝试不同的 UIModalPresentationStyles - 也许更多将在横向工作。

于 2015-01-28T17:05:19.327 回答
2

解决我的问题的另一个选项是创建 UIImagePickerController 的子类并覆盖以下方法

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

使用它而不是 UIImagePickerController 并且一切正常。

于 2012-12-30T01:41:40.523 回答
1

创建一个类别对于修复这个错误非常有帮助。并且不要忘记导入您创建的类别。这会将缺少的方法添加到 UIImagePickerController 中,并且在 iOS 6 上,它将限制它只能在 Portrait 中工作,因为文档说明了顺便说一句。

其他解决方案可能已经奏效。但是,将 SDK for iOS 8.x 编译为部署在 iOS 6.1 上,这似乎是可行的方法。

.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
于 2015-03-09T03:31:50.480 回答
1

斯威夫特 3

let imagePicker = UIImagePickerController()

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

present(imagePicker, animated: true)
于 2017-02-02T14:34:58.863 回答
1

Swift 4 及更高版本假设整个应用程序处于横向状态,并且您需要以纵向显示单个控制器。在必须是纵向的视图控制器中添加以下内容:

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

open override var shouldAutorotate: Bool {
    return false
}
于 2019-01-05T20:50:37.787 回答
0

我在隐式转换UIInterfaceOrientationPortraitUIInterfaceOrientationMaskPortrait返回值时遇到了这个崩溃问题。

更多代码背景UIPageViewControllerDelegate,仅供大家参考。

 -(UIInterfaceOrientationMask)pageViewControllerSupportedInterfaceOrientations:
(UIPageViewController *)pageViewController
{
    # return UIInterfaceOrientationPortrait;    # wrong
    return UIInterfaceOrientationMaskPortrait;  # correct
}
于 2018-03-14T02:06:14.623 回答
0

我刚刚解决了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
    }
}

也谢谢你们的回答。我刚刚剪切了工作代码并简单地重构了它。

于 2018-12-07T10:17:44.697 回答