支持的方向与应用程序没有共同的方向,并且shouldAutorotate返回YES'

时间:2012-09-22 04:06:57

标签: ipad uipopovercontroller landscape ios6

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

14 个答案:

答案 0 :(得分:91)

在IOS6中,您已在三个位置支持界面方向:

  1. .plist(或目标摘要屏幕)
  2. 您的UIApplicationDelegate
  3. 正在显示的UIViewController
  4. 如果您收到此错误,很可能是因为您在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 :(得分:63)

花了很多时间搜索一种避免子类化和添加大量代码的方法, 这是我的一行代码解决方案。

创建一个新的UIImagePickerController类别并添加

-(BOOL)shouldAutorotate{
    return NO;
}

这就是所有人!

答案 2 :(得分:43)

还有另一种情况可能会出现此错误消息。我找了几个小时,直到找到问题。阅读之后,这个帖子非常有用。

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

- (NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationPortrait;
}

这里的陷阱是xcode的intellisense建议“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)
}

答案 3 :(得分:21)

在仅景观应用中呈现图像选择器时,我遇到了类似的问题。正如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之前添加这些行。

答案 4 :(得分:10)

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

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

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

答案 5 :(得分: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];

答案 6 :(得分:4)

iOS 8 - 您可以使用UIModalPresentationPopover而不会出现任何黑客攻击。不理想,但总比没有好。

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

编辑:也许尝试不同的UIModalPresentationStyles - 也许更多将在风景中工作。

答案 7 :(得分:3)

- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.

答案 8 :(得分:2)

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

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

使用它代替UIImagePickerController,一切正常。

答案 9 :(得分:1)

创建类别对修复此错误非常有帮助。并且不要忘记导入您创建的类别。这将把缺少的方法添加到UIImagePickerController,并且在iOS 6上它将限制它仅在Document中工作,因为文档说明了btw。

其他解决方案可能有效。但是,将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

答案 10 :(得分:1)

Swift 3

let imagePicker = UIImagePickerController()

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

present(imagePicker, animated: true)

答案 11 :(得分:0)

UIInterfaceOrientationPortrait隐式转换为UIInterfaceOrientationMaskPortrait 作为返回值时,我遇到了此崩溃问题。

UIPageViewControllerDelegate上的更多代码背景,仅供所有人使用。

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

答案 12 :(得分: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
    }
}

也感谢您的回答。我刚刚剪切了工作的代码并对其进行了重构。

答案 13 :(得分:0)

在整个应用程序为横向的情况下,快速4或以上,您需要以纵向显示单个控制器。 在必须为纵向的视图控制器中,添加以下内容:

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

open override var shouldAutorotate: Bool {
    return false
}