Часто задаваемые вопросы и решения для iPhone

Здесь было много путаницы и набора соответствующих наборов вопросов о том, как могут быть реализованы приложения iPhone с правильной обработкой для авторотации в режиме Landscape / Portrait. Особенно трудно реализовать такое приложение, когда требуется начать в ландшафтном режиме. Наиболее распространенным наблюдаемым эффектом являются скремблированные макеты и области экрана, на которых штрихи больше не распознаются.

Простой поиск вопросов с тегами iphone и landscape выявляет эти проблемы, которые происходят в определенных сценариях:

Был представлен набор различных решений, некоторые из которых include полностью настраиваемую анимацию через CoreGraphics, в то время как другие основываются на наблюдении, что первый controller представления, загруженный из основного ниба, всегда отображается правильно.

Я потратил значительное количество времени на изучение этой проблемы и, наконец, нашел решение, которое является не только частичным решением, но и должно работать при всех этих обстоятельствах. Я намерен с этим сообщением CW предоставить некоторые FAQ для других, имеющих проблемы с UIViewControllers в ландшафтном режиме.

Просьба представить обратную связь и помочь улучшить качество этой Почты путем включения любых связанных наблюдений. Не стесняйтесь редактировать и публиковать другие / лучшие ответы, если вы знаете о них.

Что в документации :

В вашем controllerе просмотра переопределить shouldAutorotateToInterfaceOrientation: объявить ваши поддерживаемые ориентации интерфейса. Это свойство будет / должно проверяться инфраструктурой controllerа каждый раз, когда меняется ориентация устройства.

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orientation { return (orientation == UIInterfaceOrientationLandscapeRight); } 

Это абсолютный минимум, который должен выполнять ваш controller. Если вы хотите запустить приложение в ландшафтном режиме, вам необходимо добавить следующий ключ в ваш файл .plist :

 UIInterfaceOrientation UIInterfaceOrientationLandscapeRight 

Apple рекомендует запускать только ландшафтные приложения в режиме Landscape Right (см. HIG в разделе «Руководства пользователя»> «Начать мгновенно»).

Что нет в документации:

Немного фона:

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

Другие люди предложили использовать «MasterViewController», подключенный к главному окну, к которому другие controllerы добавляют свои представления в виде подзонов, а не подключаются непосредственно к окну. Хотя я нашел, что это решение является жизнеспособным вариантом, оно не работает корректно в случае controllerов модального представления, добавленных к этим указанным областям. Также существует проблема, если у вас есть некоторые подпункты, которые должны быть в состоянии авторотировать (что предотвратит главный controller).

Использование недокументированных API для принудительной ориентации интерфейса также не является вариантом.

Решение:

Лучшее решение, которое я нашел до сих пор, является модификацией обходного пути «MasterViewController». Вместо использования пользовательского «MasterViewController» используется UINavigationController со скрытой панелью навигации и скрытой панелью вкладок. Если все остальные представления выталкиваются из стека навигации этого controllerа, автоматическое управление controllerами в этом стеке будет осуществляться правильно.

Модальные controllerы, представленные через presentModalViewController:animated: из любого из controllerов представления в стеке навигации UINavigationController будут повернуты и отображены с правильной компоновкой. Если вы хотите, чтобы ваш controller модального просмотра мог вращаться в соответствии с другой ориентацией, чем controller родительского представления, вам нужно вернуть желаемую ориентацию из метода shouldAutorotateToInterfaceOrientation родительского controllerа, пока представлен модальный вид. Чтобы правильно восстановить ориентацию интерфейса, когда модальный controller отклонен, вам нужно убедиться, что shouldAutorotateToInterfaceOrientation возвращает желаемую ориентацию для родительского controllerа, прежде чем вы вызовите dismissModalViewController:animated: Вы можете использовать частный BOOL на вашем controllerе просмотра для управления этим (например, BOOL isModalMailControllerActive_ ).

В скором времени я добавлю часть образца кода. Сейчас только поздно. Пожалуйста, дайте мне знать, останутся ли какие-либо нерешенные проблемы или что-то непонятно в этом сообщении. Не стесняйтесь редактировать и улучшать.

У меня было интересное требование для приложения ios:

main viewController должен быть только ландшафтом, но все остальные (которые могут быть нажаты из основного) могут быть пейзажными и портретными.

Проблема occours – когда я нажимаю на новый viewController, который затем поворачивается на портретируемый – и задний вид назад – больше не является ландшафтным. Также – открытие приложения, оно не в ландшафте.

Чтобы сохранить основной ландшафт viewcontroller, независимо от того, какую ориентацию он выскочил / нажал, я сделал следующее: (in viewWillAppear 🙂

 //set statusbar to the desired rotation position [[UIApplication sharedApplication] setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:NO]; //present/dismiss viewcontroller in order to activate rotating. UIViewController *mVC = [[[UIViewController alloc] init] autorelease]; [self presentModalViewController:mVC animated:NO]; [self dismissModalViewControllerAnimated:NO]; 

Надеюсь, это поможет кому-то!

PSTested на sdk 3.2.5 ios 5.0.1.

PS Спасибо за всю информацию в этом FAQ!

Для второй маркерной точки, если вы хотите использовать pushViewController для перехода из режима «Только портрет» в «Ландшафтный», один простой взломанный я нашел, чтобы поместить следующий код в ваш viewDidLoad вашего толкаемого controllerа:

 UIViewController *viewController = [[UIViewController alloc] init]; [self presentModalViewController:viewController animated:NO]; [self dismissModalViewControllerAnimated:NO]; [viewController release]; 

Я хотел бы добавить к ответу Йоханнеса (используя UINavigationController как MasterViewController).

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

Я пробовал много трюков, чтобы исправить это, прежде чем найти тот, который работает. Больше всего работает для pushViewController: с анимированным набором в YES.

Чтобы полностью исправить проблему, я подclassифицировал UINagivationController и UINagivationController pushViewController:animated: следующим образом:

 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { // Correctly autoOrient the given view controller [self presentModalViewController:viewController animated:NO]; [self dismissModalViewControllerAnimated:NO]; // Push it as normal (now in its correct orientation) [super pushViewController:viewController animated:animated]; } 

Временно (и совершенно незаметно), отображающий controller вида, позволяет получать его обновление ориентации. Затем его можно перенести в стек навигационной системы в правильной ориентации.

Пожалуйста, дайте мне знать, если это сработает для вас. Все обновления и улучшения очень приветствуются!

Наконец, я очень рекомендую подход Йоханнеса к управлению ротацией.

РЕДАКТИРОВАТЬ: обновление на панели управления отображением из стека

Кажется, что все селекторы, связанные с popViewController, сходят с ума, когда выполняются с анимированными: ДА. В частности, controller вида анимирован в неправильном направлении. Вы можете использовать анимированные: НЕТ и ограничить использование таких анимаций другим UINavigationControllers глубже в своей иерархии (то есть те, которые вы нажимаете на стек корневого навигационного controllerа).

Любой вход очень приветствуется.

Я разрабатываю приложение для iPad, которое отображает вертикальный прокручиваемый вид галереи массива элементов при запуске. В ландшафтном режиме есть 4 предмета. В портрете есть три. При повороте ориентации iPad предполагается обновить галерею, чтобы элементы были аккуратно расположены по экрану. Затем я дважды нажимаю на элемент, чтобы перейти к модальному виду этого элемента. Затем я делаю вещи с этим предметом. Наконец, я отклоняю модальный взгляд.

Во время обновления или изменения ориентации в представлении галереи вычисляется количество отображаемых элементов в зависимости от ширины (высоты) экрана и текущей ориентации от UIViewController.interfaceOrientation.

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

Сначала я использовал значения UIViewController.view.frame.size для вычисления количества элементов галереи. Когда модальное представление было отклонено, этот размер кадра был неправильным, например, ширина и высота были отменены, хотя ориентация не изменилась, пока был показан модальный диалог.

Я переключился на использование делегата приложения ([[UIApplication sharedApplication] delegate]] и взял window.frame.size, чтобы вычислить количество элементов галереи, которые будут отображаться поперек. Window.frame.size остается корректным в отношении изменений ориентации и модальных диалогов. Элементы галереи отображаются правильно.

Это будет работать …

 UIWindow *window = [[UIApplication sharedApplication] keyWindow]; UIView *view = [window.subviews objectAtIndex:0]; [view removeFromSuperview]; [window addSubview:view]; 
  • Формирование портретной ориентации при нажатии на альбомный режим.
  • Раскадровка iPhone: сцена для портретной и пейзажной сцены
  • WPF горизонтальный DataGrid
  • Как заблокировать ориентацию во время выполнения
  • Сохранение данных и изменение ориентации
  • jQuery Мобильная блокировка блокировки
  • Что такое косвенное расширение? Что означает $ {! Var *}?
  • ориентация экрана для Android
  • Как заблокировать ориентацию в портретном режиме в веб-приложении iPhone?
  • Резюме: сделайте снимок с использованием намерения камеры и отобразите фотографию с правильной ориентацией (работает, надеюсь, на все устройства)
  • Ориентация изображения MFMailComposeViewController
  • Давайте будем гением компьютера.