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


94

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


1
вы должны принять ответ. есть много людей для помощи, и для других людей, у которых есть такая же проблема, это помогает, когда вы отмечаете правильный ответ для своей проблемы!
brush51

1
Нет!
Никакое

Ответы:


95

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

  1. .Plist (или экран сводной информации о цели)
  2. Ваш UIApplicationDelegate
  3. Отображаемый UIViewController

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

Если это ваше собственное представление, вы можете исправить его, переопределив supportedInterfaceOrientations в своем 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, а затем переопределив supportedInterfaceOrientation в своем UIApplicationDelegate:

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

3
UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightравно равно UIInterfaceOrientationMaskAllButUpsideDown UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRightравноUIInterfaceOrientationMaskLandscape
Валерий Павлов

4
Или просто используйте UIInterfaceOrientationMaskAll.
Марк Ван

Отлично. Несмотря на то, что всплывающее окно «только для портретной ориентации» будет работать в альбомной ориентации, оно не может модально представлять контроллер просмотра только для альбомной ориентации.
Нил Эхардт 01

Нет! Решение не работал над прошивкой 7 :(. Stackoverflow.com/questions/23005351/...
AsifHabib

Работал на iOS 8. Правда, пришлось добавить поддержку портретной ориентации в plist. Спасибо.
Ярослав

65

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

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

-(BOOL)shouldAutorotate{
    return NO;
}

Вот и все, ребята!


1
Сработал и у меня, не тестировал полностью, но, похоже, пока помогает.
migs647

2
Кажется, это лучшее решение.
Джулиан

2
Работает! Это здорово, и это действительно помогло мне в крайнем случае. Спасибо, доктор Луиджи !!
брэк

1
Ницца. У меня работает на iOS 6. Вы также можете сделать это настраиваемым в категории для полной гибкости.
Джаред Иган

3
не работает в iOS7, метод категорий даже не вызывается (хотя и включен в pch)
Питер Ляпису

43

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

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

- (NSUInteger)supportedInterfaceOrientations {

    return UIInterfaceOrientationPortrait;
}

Ловушка здесь заключалась в том, что intellisense xcode предложил "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)
}

5
случилось со мной по той же причине
ChenXin

Я бы хотел, чтобы Apple просто сделала возвращаемый тип UIInterfaceOrientationMask, чтобы было немного более очевидно, что нужно вернуть.
LightningStryk

Ответ Джекпирса выглядит правильным. Но если заглянуть в info.plist, можно увидеть UISupportedInterfaceOrientations с UIInterfaceOrientationPortrait, UIInterfaceOrientationLandscapeLeft, UIInterfaceOrientationLandscapeRight. Нет МАСКА здесь
onmyway133

1
@onmyway: Это правда, значения plist не изменились. В предыдущей версии для iOS Apple использовала «не» значения маски внутри кода. Это некоторые устаревшие вещи. Я предполагаю, что Apple теперь немного меняет значения plist внутри.
JackPearse

Мое приложение раньше работало без этой проблемы сбоя на симуляторе iPad Xcode 6.2. И он разбился после того, как я обновился до Xcode 6.3 несколько дней назад. Теперь это решение решает мою проблему. Спасибо большое :-)
Golden Thumb

22

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

// 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 файла.


У меня есть приложение только для портретов! и я хочу показать камеру в ландшафтном режиме. любое решение ?????
AsifHabib

Траусти не сработал? У меня такая же проблема, и я пробовал ваш код, но по-прежнему появляется такое же исключение *** Завершение работы приложения из-за неперехваченного исключения 'UIApplicationInvalidInterfaceOrientation', причина: 'Поддерживаемые ориентации не имеют общей ориентации с приложением, и shouldAutorotate возвращает ДА ​​..... ... я также поставил точку останова на метод категории UIimagePickerView shouldAutorotate, достигающий этого места и не возвращающий, но все еще выдающий это исключение .... Мое приложение - это приложение только для ландшафта ... пожалуйста, помогите мне
Vishal16

Также работает, чтобы заставить SKStoreProductViewController отображаться в портретной ориентации, когда все приложение находится в альбомной ориентации в iOS 8. Спасибо.
Ярослав

11

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

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

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


Кстати, я изначально нашел это по адресу: stackoverflow.com/questions/12522491/…
Робби

Это был правильный ответ, прямо от Apple, и тогда мне просто пришлось следовать тем же инструкциям, но сделать это в Swift для приложения, ориентированного на iOS 8. Все работает отлично. AppDelegate устанавливает supportedInterfaceOrientationsForWindow как в альбомную, так и в портретную, каждый отдельный быстрый набор файлов переопределяет func supportedInterfaceOrientations только в альбомной ориентации, поэтому представление не будет вращаться, но когда необходимо загрузить портретное представление (в моем случае SKStoreProductViewController), оно работает!
RanLearns

Боже, есть так много предлагаемых решений, и это, безусловно, не имеет наивысших баллов, но оно действительно правильное. Проверено на iOS 10 и 9. Больше ничего не работает.
Демиан Тернер

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

1
Неважно, он обнаруживает NonRotatingUIImagePickerController сейчас, но ничего не отображается ... @poetowen
Destiny Dawn

4

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

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

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


3
- (BOOL)shouldAutorotate {
    return NO;
}

-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

This removes the crash.

2

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

@interface MyImagePickerController ()

@end

@implementation MyImagePickerController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

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


1

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

Другие решения могли сработать. Но с 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

1

Swift 3

let imagePicker = UIImagePickerController()

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

present(imagePicker, animated: true)

0

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

Больше фона кода 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
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.