Поддерживаемые ориентации не имеют общей ориентации с приложением, и shouldAutorotate возвращает ДА ​​'

Мое приложение (iPad, iOS 6) - это приложение, использующее только ландшафт, но когда я пытаюсь использовать UIPopoverController для отображения библиотеки фотографий, это вызывает эту ошибку: Supported orientations has no common orientation with the application, and shouldAutorotate is returning YES. Я пытался изменить много кода, но мне не повезло.

Ответ 1

В IOS6 вы поддерживаете ориентацию интерфейса в трех местах:

  • .plist(или экран итоговой задачи)
  • Ваш UIApplicationDelegate
  • Отображаемый UIViewController

Если вы получаете эту ошибку, это, скорее всего, потому, что представление, которое вы загружаете в своем UIPopover, поддерживает только портретный режим. Это может быть вызвано Game Center, iAd или вашим собственным представлением.

Если это ваш собственный взгляд, вы можете исправить его, переопределив supportInterfaceOrientations на вашем 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;
}

Если это не ваш собственный взгляд (например, GameCenter на iPhone), вам нужно убедиться, что ваш .plist поддерживает портретный режим. Вам также необходимо убедиться, что ваш UIApplicationDelegate поддерживает представления, отображаемые в портретном режиме. Вы можете сделать это, отредактировав свой .plist, а затем переопределив поддерживаемую внешнюю оболочку на вашем UIApplicationDelegate:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}

Ответ 2

Проведя много времени, пытаясь избежать подклассификации и добавления тонны кода, здесь мое однострочное решение.

Создайте новую категорию UIImagePickerController и добавьте

-(BOOL)shouldAutorotate{
    return NO;
}

Что все люди!

Ответ 3

В противном случае может появиться сообщение об ошибке. Я искал часы, пока не нашел проблему. Этот поток был очень полезен после прочтения его пару раз.

Если ваш главный контроллер представления повернут в альбомную ориентацию, и вы вызываете пользовательский контроллер подзадачи, который должен отображаться в портретной ориентации, это сообщение об ошибке может случиться, когда ваш код выглядит следующим образом:

- (NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationPortrait;
}

Ловушка здесь была xcode intellisense, которая предложила "UIInterfaceOrientationPortrait", и мне это не волновало. На первый взгляд это казалось правильным.

Правая маска называется

UIInterfaceOrientationMaskPortrait

Обратите внимание на маленький инфикс "Маска" , иначе ваше подчиненное приложение закончит исключение и указанное выше сообщение об ошибке.

Новые перечисления смещаются по битам. Предыдущие перечисления возвращают недопустимые значения!

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

Ответ 4

У меня была аналогичная проблема при представлении подборщика изображений в приложении только для ландшафта. Как предложил д-р Луиджи, я добавил следующую категорию в начале моего контроллера.

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

Проще всего добавить эти строки непосредственно перед @implementation вашего файла ViewController.m.

Ответ 5

В моем коде появилось одно и то же сообщение об ошибке. Я нашел это, это ошибка, о которой сообщает Apple:

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

Его решение - исправить его в AppDelegate. Я реализовал его, и он работает для меня!

Ответ 6

У меня была та же проблема, и этот ответ fooobar.com/questions/71714/... работает для меня. Интересно, есть ли более элегантное решение.

Мой код:

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

Ответ 7

iOS 8 - вы можете использовать UIModalPresentationPopover без каких-либо хаков для отображения в popover. Не идеально, но лучше, чем ничего.

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

Изменить: возможно, попробуйте разные UIModalPresentationStyles - возможно, больше будет работать в ландшафте.

Ответ 8

- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.

Ответ 9

Другой вариант, который разрешил мои проблемы, заключался в создании подкласса UIImagePickerController и переопределении метода ниже.

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

Используйте это вместо UIImagePickerController, и все работает отлично.

Ответ 10

Создание категории действительно полезно для исправления этой ошибки. И не забудьте импортировать созданную вами категорию. Это добавит отсутствующий метод в UIImagePickerController и на iOS 6, он ограничит его работу в Portrait только в том случае, если в документации указано btw.

Другие решения, возможно, сработали. Но с SDK для 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

Ответ 11

Swift 3

let imagePicker = UIImagePickerController()

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

present(imagePicker, animated: true)

Ответ 12

Я столкнулся с этой проблемой при UIInterfaceOrientationPortrait при преобразовании UIInterfaceOrientationPortrait в UIInterfaceOrientationMaskPortrait неявно в качестве возвращаемого значения.

Больше кода фона на UIPageViewControllerDelegate, просто FYI для всех вас.

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

Ответ 13

Я только что решил проблему для 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
    }
}

Спасибо, ребята, за ваши ответы. Я только что отрезал обработанный код и просто реорганизовал его.