支持的方向与应用程序没有通用的方向,并且应该Autorotate返回YES'


92

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


1
您应该接受答案。有很多人可以寻求帮助,而对于遇到同样问题的其他人,当您为问题标出正确答案时,它会有所帮助!
brush51

1
没有!在iOS 7上没有解决方案:((
headbang

Answers:


94

在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;
}

3
UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight等于UIInterfaceOrientationMaskAllButUpsideDown UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight等于UIInterfaceOrientationMaskLandscape
Valerii Pavlov 2012年

4
或者只是使用UIInterfaceOrientationMaskAll。
Mark Wang

完善。即使“仅纵向”弹出框将在横向中起作用,但它不能模态呈现仅横向视图控制器。
Neal Ehardt

没有!解决方案没有工作在iOS 7 :(。 stackoverflow.com/questions/23005351/...
AsifHabib

在iOS 8上工作。不过,必须将肖像支持添加到plist。谢谢。
Yaroslav

65

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

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

-(BOOL)shouldAutorotate{
    return NO;
}

那是所有人!


1
同样为我工作,还没有完全测试,但到目前为止似乎可以解决问题。
migs647

2
这似乎是最好的解决方案。
朱利安

2
作品!这很棒,确实帮了我一些忙。感谢路易吉博士!
brack 2012年

1
真好 在iOS 6上对我有效。您也可以在类别中将此设置为可配置,以实现全面的灵活性。
Jared Egan

3
在iOS7中不起作用,甚至没有调用category方法(尽管已包含在pch中)
Peter Lapisu 2013年

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)
}

5
发生在我身上出于同样的原因

我希望苹果将返回类型设置为UIInterfaceOrientationMask,以便使返回的内容更加明显。
LightningStryk

Jackpearse的答案看起来正确。但是,当查看info.plist时,会出现带有UIInterfaceOrientationPortrait,UIInterfaceOrientationLandscapeLeft,UIInterfaceOrientationLandscapeRight的UISupportedInterfaceOrientations。无MASK这里
onmyway133

1
@onmyway:是的,plist的值没有改变。在以前的iOS版本中,Apple在代码中使用了“非”掩码值。这是一些遗留的东西。我认为苹果现在在内部对plist值进行了位移。
JackPearse'2

我的应用程序过去可以在Xcode 6.2的iPad模拟器上正常运行而不会出现崩溃问题。我几天前升级到Xcode 6.3之后,它崩溃了。现在,此解决方案解决了我的问题。非常感谢:-)
Golden Thumb

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之前添加这些行是最简单的。


我有一个只有人像的应用!我想以横向模式显示相机。任何解决方案?????
AsifHabib 2014年

特劳斯蒂没用?我有同样的问题,我尝试了您的代码,但仍然出现相同的异常***由于未捕获的异常'UIApplicationInvalidInterfaceOrientation',终止了应用程序,原因:'支持的方向与应用程序没有共同的方向,并且应该AutoAutoate返回YES。 ......我也提上UIimagePickerView类方法shouldAutorotate一个断点到达那里,并没有返回,但仍然给这个例外....我的应用程序是景观唯一的应用程序......请帮助我
Vishal16

当整个应用在iOS 8中为横向时,也可以强制SKStoreProductViewController以纵向显示。谢谢。
Yaroslav

11

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

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

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


顺便说一句,我最初是在以下位置找到这个的:stackoverflow.com/questions/12522491/…–
Robby

直接从苹果公司得到的答案是正确的,然后我只需要遵循相同的说明,但是在Swift中为目标为iOS 8的应用程序就可以做到。一切都很好。AppDelegate将supportedInterfaceOrientationsForWindow设置为Landscape和Portrait,每个单独的快速文件集都将funcsupportedInterfaceOrientations设置为Landscape,这样视图就不会旋转,但是当需要加载人像视图(在我的情况下为SKStoreProductViewController)时,它就可以工作!
RanLearn

耶兹,有很多建议的解决方案,到目前为止,这还没有最高的建议,但确实是正确的。在iOS 10和9上进行了测试。
Demian Turner

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

我尝试这样做,但是当我单击按钮以调用代码但没有显示任何内容时,我也尝试添加@interface NonRotatingUIImagePickerController : UIImagePickerController @end @implementation NonRotatingUIImagePickerController - (BOOL)shouldAutorotate { return NO; } @end到代码中,但是我的代码无法检测到NonRotatingUIImagePickerController。
Destiny Dawn 2012年

1
没关系,它现在检测到NonRotatingUIImagePickerController,但仍无显示... @poetowen
Destiny Dawn

4

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

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

编辑:也许尝试不同的UIModalPresentationStyles-也许更多的可以在横向使用。



2

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

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

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


1

创建类别确实有助于修复此错误。并且不要忘记导入您创建的类别。这会将缺少的方法添加到UIImagePickerController中,并且在iOS 6上,它将仅在文档说明btw时才限制只能在Portrait中使用。

其他解决方案可能已经起作用。但是,通过将iOS 8.x SDK编译为可在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

1

迅捷3

let imagePicker = UIImagePickerController()

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

present(imagePicker, animated: true)

0

隐式转换UIInterfaceOrientationPortraitUIInterfaceOrientationMaskPortrait为返回值时遇到了崩溃问题。

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

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

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

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


0

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

override open var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

open override var shouldAutorotate: Bool {
    return false
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.