Подтвердить что ты не робот

Авторотация в iOS 6 имеет странное поведение

У меня есть приложение UITabBarController, которое воспроизводит видео и показывает другую информацию на других вкладках UITabBar. В iOS 6 UIView методы поворота устарели, и теперь мне нужно использовать методы shouldAutoRotate и supportedInterfaceOrientations. Для воспроизведения видео я использую MPMoviePlayerViewController.

Как вращать только этот просмотр плеера? Я могу только вращать все приложение, но не хочу этого делать. Я представляю MPMoviePlayerViewController, но он не вращается, как в iOS 5 и ранее.

В настройке plist я установил только ориентацию портрета 1. Если я установил другое - все приложение будет повернуто.

4b9b3361

Ответ 1

Из примечаний к выпуску Apple iOS 6 SDK:

Авторизация изменяется в iOS 6. В iOS 6 метод shouldAutorotateToInterfaceOrientation: UIViewController устарел. Вместо этого вы должны использовать методы supportedInterfaceOrientationsForWindow: и shouldAutorotate.

Больше ответственности переместится в приложение и делегат приложения. Теперь контейнеры iOS (например, UINavigationController) не проконсультируют своих детей, чтобы определить, должны ли они авторотировать. По умолчанию для поддерживаемых ориентаций интерфейсов приложений и представлений установлены UIInterfaceOrientationMaskAll для идиомы iPad и UIInterfaceOrientationMaskAllButUpsideDown для идиомы iPhone.

Поддерживаемые интерфейсы интерфейса просмотра могут меняться со временем - даже ориентированные на приложения интерфейсы могут меняться со временем. Система запрашивает самый полный полноэкранный контроллер (обычно контроллер корневого представления) для поддерживаемых ориентаций интерфейса всякий раз, когда устройство вращается или всякий раз, когда диспетчер представлений представлен полноэкранным модальным стилем презентации. Кроме того, поддерживаемые ориентации извлекаются только в том случае, если этот контроллер представления возвращает YES из его метода toAutorotate. Система пересекает поддерживаемые ориентацией представления контроллеры с ориентациями, поддерживаемыми приложениями (как определено в файле Info.plist или приложении для делегатов приложения: supportedInterfaceOrientationsForWindow: method), чтобы определить, нужно ли вращаться.

Система определяет, поддерживается ли ориентация, пересекая значение, возвращаемое поддерживаемыми приложениямиInterfaceOrientationsForWindow: метод со значением, возвращаемым методом supportedInterfaceOrientations самого верхнего полноэкранного контроллера. Метод setStatusBarOrientation: animated: не устаревает полностью. Теперь он работает только в том случае, если метод supportedInterfaceOrientations из самого верхнего полноэкранного контроллера отображает 0. Это заставляет вызывающего абонента следить за тем, чтобы ориентация строки состояния была согласованной.

Для совместимости контроллеры представлений, которые все еще реализуют метод shouldAutorotateToInterfaceOrientation: не получают новых действий по авторотации. (Другими словами, они не возвращаются к использованию приложения, делегата приложения или файла Info.plist для определения поддерживаемых ориентаций.) Вместо этого метод shouldAutorotateToInterfaceOrientation: используется для синтеза информации, которая будет возвращена методом supportedInterfaceOrientations.

Если вы хотите, чтобы все ваше приложение вращалось, вы должны настроить Info.plist для поддержки всех ориентаций. Теперь, если вы хотите, чтобы определенный вид был только портретистом, вам нужно будет сделать какой-то подкласс и переопределить методы авторотации, чтобы возвращать только портрет. У меня есть пример:

fooobar.com/questions/67650/...

Ответ 2

ух! Прошло пол дня, и проблема решена! Он он.

Как говорится в вышеприведенной документации, это действительно так! Основные моменты:

Больше ответственность переходит к приложению и делегату приложения. Теперь контейнеры iOS (например, UINavigationController) не консультироваться их детей, чтобы определить, должны ли они авторотировать. От интерфейс по умолчанию, приложение и поддерживаемые интерфейсы просмотра ориентации установлены на UIInterfaceOrientationMaskAll для iPad идиома и UIInterfaceOrientationMaskAllButUpsideDown для iPhone идиомы.

Итак, в любой момент, когда что-то с корневым контроллером изменяется, система запрашивает делегат приложения "Итак, что мы? Вращаемся или нет?"

Если "вращение":

поддерживаемые ориентации извлекаются только в том случае, если этот контроллер представления возвращает YES из его метода toAutorotate

тогда система запрашивает у нашего делегата приложения для

- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {    

    return ...;
}

Это действительно очень просто.

Как определить, когда мы должны разрешать портрет или пейзаж и т.д. - зависит от вас. Тестирование для корневого контроллера для меня не срабатывало из-за некоторых точек, но это работает:

- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {    

    return self.fullScreenVideoIsPlaying ?
        UIInterfaceOrientationMaskAllButUpsideDown :
        UIInterfaceOrientationMaskPortrait;
}

Свойство "fullScreenVideoIsPlaying" настраивается мной вручную, когда мне это нужно.

Единственное важное, что нужно быть осторожным, это перечисление. Как говорится в документах... (читайте внимательно над iPad/iPhone). Таким образом, вы можете играть с теми, которые вам нужны.

Еще одна крошечная вещь - это некорректное поведение после закрытия контроллера плеера. Был один раз, когда он не менял ориентацию, но это произошло однажды и каким-то странным образом, и только в симуляторе (конечно, только iOS 6). Поэтому я даже не мог реагировать, поскольку это произошло неожиданно, и после быстрого нажатия на некоторые другие элементы моего приложения он повернулся к нормальной ориентации. Итак, не уверен - может быть, какая-то задержка в работе симулятора или что-то (или, действительно, ошибка:)).

Удачи!

Ответ 3

У меня была такая же проблема с моим приложением.

Как работает ротация в iOS 6.

= > когда вы используете UINavigationCOntroller метод в AppDelegate

- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window    
{
   return 
}

решает, вращаться или нет.

= > , когда представление представлено в стиле модальной презентации, метод

- (BOOL)shouldAutorotate

который находится внутри viewController для этого представления, запускает метод в appDelegate. И как 1-й случай appDelegate решает повернуть или нет.

Мое решение::

Что я сделал для Модальной презентации, так это. Создал флаг в делегате приложения.

когда флаг имеет значение "ДА", он вращается в "Пейзаж", а другой - только "Портрет".

- (NSUInteger)application:(UIApplication*)application
supportedInterfaceOrientationsForWindow:(UIWindow*)window
{
    if(self.shouldRotate ) //shouldRotate is my flag
    {
        self.shouldRotate = NO;
        return (UIInterfaceOrientationMaskAll);
    }
    return (UIInterfaceOrientationMaskPortrait);
}

И для переключения между вращениями

- (BOOL)shouldAutorotate
{
    YourAppDelegate *mainDelegate = (YourAppDelegate*)[[UIApplication sharedApplication]delegate];
    mainDelegate.shouldRotate = YES;

    return YES;
}

Примечание. Это работает только для представления, которое представлено в режиме "Хорошо".         Использование флага, а не хорошая практика кодирования.

Ответ 4

Вы также можете подклассифицировать UITabBarController, чтобы он спрашивал своих детей о shouldAutorotate и поддержкеInterfaceOrientation следующим образом:

@implementation MyTabBarController

-(BOOL)shouldAutorotate
{
    return [self.selectedViewController shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [self.selectedViewController supportedInterfaceOrientations];
}

@end

Затем вы просто используете свой собственный контейнер вместо стандартного, и он работает! просто протестирован.

Ответ 5

К сожалению, вам нужно включить все ориентации в вашем plist и использовать supportedInterfaceOrientations на всех контроллерах представления, которые вы не хотите вращать. (В вашем случае все, кроме видеопроигрывателя.)

Ответ 6

Попробуйте это,

Если TabBarController является RootViewController для окна, Затем создайте собственный класс, который наследует TabBarController, например CustomTabBarController.h

Добавить метод ниже в CustomTabBarController.h

-(NSUInteger)supportedInterfaceOrientations // Must return Orientation Mask

Наконец, позвоните ниже в AppDelegate.m

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window  {
   if( [self.window.rootViewController supportedInterfaceOrientations]!=0) 
     {
        return [self.window.rootViewController supportedInterfaceOrientations];
    }
    return UIInterfaceOrientationMaskAll;
}

Ответ 7

Я нашел, что самый простой способ установить это - использовать кнопки "поддерживаемые интерфейсные ориентации", которые вы можете увидеть, если вы посмотрите на Цели.... Сводная вкладка (в разделе Информация о развертывании iPhone/iPad).

В основном это графический интерфейс для установки файла plist