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

94

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

Судьба рассвет
источник
1
вы должны принять ответ. есть много людей для помощи, и для других людей, у которых есть такая же проблема, это помогает, когда вы отмечаете правильный ответ для своей проблемы!
brush51
1
Нет!
Никакое
Лучший ответ здесь stackoverflow.com/questions/20468335/…
Дэмиен Ромито

Ответы:

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, и все работает нормально.

EquiAvia Tech
источник
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
Helge Staedtler
источник
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
}
Гал Бланк
источник