У меня есть приложение для iPhone, которое использует UINavigationController
для представления интерфейса детализации: сначала одно представление, затем другое, до четырех уровней в глубину. Я хочу, чтобы первые три вида были ограничены портретной ориентацией, и только последний вид должен иметь возможность вращаться в альбомную. При возврате из четвертого вида к третьему и четвертому виду в альбомной ориентации я хочу, чтобы все повернулось обратно в портретную ориентацию.
В iOS 5 я просто определил shouldAutorotateToInterfaceOrientation:
в каждом из своих контроллеров представления, чтобы он возвращал YES для допустимых ориентаций. Все работало, как описано выше, включая возврат к портретной ориентации, даже если устройство удерживалось в альбомной ориентации при возврате из контроллера представления №4 в №3.
В iOS 6 все контроллеры представления вращаются в альбомную ориентацию, нарушая те, которые не были предназначены. В примечаниях к выпуску iOS 6 говорится
Больше ответственности переносится на приложение и его делегата. Теперь контейнеры iOS (такие как
UINavigationController
) не консультируются со своими дочерними элементами, чтобы определить, следует ли им выполнять авторотацию. [...] Система запрашивает самый верхний полноэкранный контроллер представления (обычно корневой контроллер представления) о поддерживаемых ориентациях интерфейса всякий раз, когда устройство вращается или когда контроллер представления представлен в полноэкранном модальном стиле представления. Более того, поддерживаемые ориентации извлекаются, только если этот контроллер представления возвращает YES из своегоshouldAutorotate
метода. [...] Система определяет, поддерживается ли ориентация, пересекая значение, возвращаемое методом приложения,supportedInterfaceOrientationsForWindow:
со значением, возвращаемымsupportedInterfaceOrientations
методом самого верхнего полноэкранного контроллера.
Итак, я создал подклассы UINavigationController
, присвоил своему MainNavigationController
логическому свойству landscapeOK
и использовал его, чтобы вернуть допустимые ориентации supportedInterfaceOrientations
. Затем в каждом из моих viewWillAppear:
методов контроллеров представления у меня есть такая строка
[(MainNavigationController*)[self navigationController] setLandscapeOK:YES];
сказать мне MainNavigationController
желаемое поведение.
Возникает вопрос: если я сейчас перейду к своему четвертому виду в портретном режиме и переверну телефон, он повернется в альбомный. Теперь я нажимаю кнопку «Назад», чтобы вернуться к третьему виду, который должен работать только в портретной ориентации. Но не вращается назад. Как мне это сделать?
Я попытался
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]
в viewWillAppear
методе моего третьего контроллера представления, но он ничего не делает. Это неправильный метод вызова или, может быть, неправильное место для его вызова, или я должен реализовать все это совершенно по-другому?
источник
Добавить CustomNavigationController
Переопределите в нем эти методы:
Теперь добавьте все ориентации в список
В контроллере представления добавьте только необходимые:
эти методы переопределяют методы контроллера навигации
источник
ViewController
были в портретном режиме, а мойViewController
- в режиме «Пейзаж и портрет». Я также поддерживаю как iOS 5.0, так и iOS 6.0. Вот почему я не понимаю, как обойтись, но это отличное решение. Я добавляю CustomNavigationController в свой контроллер корневого представления и предоставляю поддержку в соответствии со своими потребностями. Еще раз спасибо.После просмотра каждого ответа на бесчисленное количество похожих вопросов по SO, ни один из ответов не помог мне, но они дали мне некоторые идеи. Вот как я решил проблему:
Во-первых, убедитесь, что поддерживаемые ориентации интерфейса в целевом объекте вашего проекта содержат все ориентации, которые вы хотите использовать для вращающегося вида.
Затем создайте категорию
UINavigationController
(поскольку Apple говорит не создавать подклассы):Импортируйте эту категорию и контроллер представления, который вы хотите вращать (я назову его
RotatingViewController
), в контроллер представления самого высокого уровня, который должен содержать ваш контроллер навигации. В этом контроллере представления выполнитеshouldAutorotate
следующие действия. Обратите внимание, что это не должен быть тот же контроллер представления, который вы хотите повернуть.Наконец, в вашей
RotatingViewController
реализацииshouldAutorotate
иsupportedInterfaceOrientations
следующим образом:Причина, по которой вам нужно это сделать, заключается в том, что iOS 6 передает управление вращением контроллеру корневого представления, а не контроллеру вида сверху. Если вы хотите, чтобы вращение отдельного представления велось иначе, чем другие представления в стеке, вам нужно написать для него конкретный случай в контроллере корневого представления.
источник
У меня недостаточно репутации, чтобы комментировать ответ @Brian, поэтому я добавлю здесь свое примечание.
Брайан упомянул, что iOS6 передает управление вращением rootViewController - это может быть не только UINavigationController, как уже упоминалось, но также UITabBarController, которым он был для меня. Моя структура выглядит так:
Поэтому я добавил методы сначала в пользовательский UITabBarController, затем в пользовательский UINavigationController и, наконец, в конкретный UIViewController.
Пример из UITabBarController и UINavigationController:
источник
Я хотел бы дать частичный ответ на свой вопрос. Я обнаружил, что следующая строка кода, используемая в
viewWillAppear
моем третьем методеUIViewController
, работает:Но мне это решение не очень нравится. Он использует уловку для присвоения свойства только для чтения, которое, согласно документации Apple, представляет физическую ориентацию устройства. Это похоже на указание iPhone перейти в правильную ориентацию в руке пользователя.
Мне очень хочется оставить это в моем приложении, потому что оно просто работает. Но это кажется неправильным, поэтому я хотел бы оставить этот вопрос открытым для чистого решения.
источник
Это я использую для поддержки ориентации в iOS 6.0.
источник
Это очень просматриваемая ветка. Я подумал, что добавлю то, что считаю самым простым ответом. Это работает для ios8 и выше
и
Вот и все. Наслаждайтесь!
О, и мои ViewControllers встроены в контроллер навигации, который мне не нужно было подклассифицировать или настраивать каким-либо образом.
источник
Это может не сработать для всех, но для меня это работает отлично. Вместо реализации ...
в viewWillAppear во всех моих контроллерах я решил централизовать этот процесс внутри своего подкласса UINavigationController, переопределив метод UINavigationControllerDelegate
navigationController:willShowViewController:animated:
Я обнаружил, что этот метод делегата не вызывается при извлечении VC из стека навигации. Для меня это не было проблемой, потому что я обрабатываю обратную функциональность из своего подкласса UINavigationController, так что я могу установить правильные кнопки панели навигации и действия для определенных VC, например, этого ...
Вот как
back
выглядит мой метод для обработки выталкивания VC из стека и установки соответствующего предпочтения вращения ...Итак, как вы можете видеть, в основном все, что происходит, - это сначала я устанавливаю мне два свойства ...
в
navigationController:willShowViewController:animated:
котором будет определено, какие поддерживаемые ориентации находятся в том виртуальном канале, который будет представлен. При извлечении VC вызывается мой собственный метод «back», и затем я устанавливаю isLandscapeOK на то, что было сохранено через предыдущее значение VCLandscapeOK.Как я уже сказал, это может работать не для всех, но для меня это отлично работает, и мне не нужно беспокоиться о добавлении кода в каждый из моих контроллеров представления, я смог сохранить все это централизованно в подклассе UINavigationController.
Надеюсь, это поможет кому-то так же, как и мне. Спасибо, Джереми.
источник
Перейдите к файлу Info.plist и внесите изменения
источник
Вы хотите заставить портрет приложения iOS 6 только тогда, когда вы можете добавить в подкласс UIViewController методы ниже
источник
NSUInteger
выдает предупреждение, несмотря на то, что это правильный тип var. если у вас есть ОКР, используйтеUIInterfaceOrientationMask
вместо этого.Я хотел, чтобы все мои VC были заблокированы для портретной ориентации, кроме одного. Это то, что у меня сработало.
В корневом контроллере представления определите тип контроллера представления, который находится в верхней части окна, и установите соответствующую ориентацию приложения в методе supportedInterfaceOrientations . Например, мне нужно, чтобы мое приложение вращалось только тогда, когда веб-просмотр находился на вершине стека. Вот что я добавил в свой rootVC:
источник
[[Utils getAppDelegate] appNavigationController]
. Utils Я предполагаю, что у вас есть какой-то класс, но я не понимаю, что вы в нем делаете. Любая помощь была бы замечательной!У меня недостаточно репутации, чтобы ответить на вопрос @Ram S в ответе @micmdk, поэтому я добавлю здесь свое примечание.
Когда вы используете UITabbarController , попробуйте изменить self.viewControllers.lastObject в коде @ micmdk на self.selectedViewController следующим образом:
источник
Вы можете реализовать и переопределить переменные shouldAutorotate () и supportedInterfaceOrientations во всех ваших классах контроллера представления, которые должны быть представлены в ориентации, отличной от ориентации, определенной в PLIST вашего приложения.
Однако в нетривиальном пользовательском интерфейсе вы можете столкнуться с проблемой добавления его в десятки классов, и вы не хотите делать все из них подклассами нескольких общих, которые его поддерживают (MyBaseTableViewController, MyBaseNavigationController и MyBaseTabBarController).
Поскольку вы не можете напрямую переопределить этот метод / var в UIViewController, вы можете сделать это в его подклассах, которые обычно являются вашими базовыми классами, такими как UITableViewController, UINavigationController и UITabBarController.
Таким образом, вы можете реализовать несколько расширений и по-прежнему настроить MyPreciousViewController для отображения в другой ориентации, чем все другие, такие как этот фрагмент кода Swift 4:
источник
Я решил такую же проблему.
Если вы используете
UINavigationController
для нажатия контроллеров представления, вы должны установить методы ниже.Вместо
LoginViewController
использования, котороеUIViewController
вы хотите показать. В моем случае я хочу показатьLoginViewController
вPortrait
режиме другойViewControllers
вlandscape
режиме.источник
Используйте следующий метод для решения этой проблемы
верните только нужную вам ориентацию !!!
источник