Как было сообщено в других вопросах здесь, на SO, iOS 5 изменяет способ обратного вызова вращения для Контроллеры с разделенным представлением отправляются в соответствии с этим примечанием к выпуску. Это не обман (я думаю), так как я не могу найти еще один вопрос по SO, который касается того, как настроить использование контроллера разделения представления в iOS 5, чтобы справиться с изменением:
Обратные вызовы поворота в iOS 5 не применяются к контроллерам просмотра, которые отображаются в полноэкранном режиме. Это означает, что если ваш код представляет контроллер представления поверх другого контроллера представления, а затем пользователь впоследствии поворачивает устройство в другую ориентацию, при увольнении базовый контроллер (т.е. представляющий контроллер) не получит никаких обратных вызовов вращения. Однако обратите внимание, что представляющий контроллер получит вызов viewWillLayoutSubviews при его повторном отображении, а свойство interfaceOrientation можно запросить из этого метода и использовать для правильной компоновки контроллера.
У меня возникли проблемы с настройкой кнопки всплывающего окна в моем корневом контроллере разделенного представления (тот, который должен отображать вид левой панели во всплывающем окне, когда вы находитесь в портретной ориентации). Вот как моя последовательность запуска приложения работала в iOS 4.x, когда устройство находится в альбомном режиме:
Установите контроллер разделения представления в окно с помощью
[window addSubview:splitViewController.view]; [window makeKeyAndVisible];
. Это приводит к тому, что делегат вызываетсяsplitViewController:willHideViewController:withBarButtonItem:forPopoverController:
(т. Е. Имитирует альбомный -> портретный поворот), даже если устройство уже находится в ландшафтном режиме.Представьте полноэкранный модальный экран (мой экран загрузки), который полностью покрывает разделенное изображение внизу.
Завершите загрузку и закройте модальный экран загрузки. Поскольку устройство находится в ландшафтном режиме, когда открывается контроллер разделения представления, это вызывает
splitViewController:willShowViewController:invalidatingBarButtonItem:
для вызова делегата (т. Е. Имитирует портретный -> альбомный поворот), тем самым делая недействительным элемент кнопки панели, удаляя его с правой стороны. разделенного представления и оставляя нас там, где мы хотим быть. Ура!
Итак, проблема в том, что из-за изменения, описанного в этом примечании к выпуску, все, что происходит внутри iOS 4.3, в результате которого вызывается splitViewController:willShowViewController:invalidatingBarButtonItem:
, больше не происходит в iOS 5. Я попытался создать подкласс UISplitViewController, чтобы я мог предоставить настраиваемую реализацию viewWillLayoutSubviews
, как было предложено в примечании к выпуску, но я не знаю, как воспроизвести желаемую последовательность внутренних событий, которые запускает iOS 4. Я пробовал это:
- (void) viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
UINavigationController *rightStack = [[self viewControllers] objectAtIndex:1];
UIViewController *rightRoot = [[rightStack viewControllers] objectAtIndex:0];
BOOL rightRootHasButton = ... // determine if bar button item for portrait mode is there
// iOS 4 never goes inside this 'if' branch
if (UIInterfaceOrientationIsLandscape( [self interfaceOrientation] ) &&
rightRootHasButton)
{
// Manually invoke the delegate method to hide the popover bar button item
[self.delegate splitViewController:self
willShowViewController:[[self viewControllers] objectAtIndex:0]
invalidatingBarButtonItem:rightRoot.navigationItem.leftBarButtonItem];
}
}
В основном это работает, но не на 100%. Проблема в том, что самостоятельный вызов метода делегата не фактически делает недействительным элемент кнопки панели, поэтому при первом повороте в портретную ориентацию система считает, что элемент кнопки панели все еще установлен правильно и не попробуйте переустановить. Только после того, как вы снова повернетесь в альбомную, а затем обратно в портретную, система вернется в правильное состояние и фактически установит элемент кнопки всплывающей панели в портретном режиме.
На основе этот вопрос, я также попытался вызвать все обратные вызовы вращения вручную вместо запуска метода делегата, например:
// iOS 4 never goes inside this 'if' branch
if (UIInterfaceOrientationIsLandscape( [self interfaceOrientation] ) &&
rightRootHasButton)
{
[self willRotateToInterfaceOrientation:self.interfaceOrientation duration:0];
[self willAnimateRotationToInterfaceOrientation:self.interfaceOrientation duration:0];
[self didRotateFromInterfaceOrientation:self.interfaceOrientation];
}
Однако это просто вызывает бесконечный цикл обратно в viewWillLayoutSubviews
:(
Кто-нибудь знает, какой правильный способ имитировать события вращения в стиле iOS4 для контроллера разделения представления, который появляется из-за полноэкранного модального окна? Или вам вообще не следует их моделировать, и есть ли еще один передовой подход, который стал стандартом для iOS5?
Любая помощь действительно приветствуется, поскольку эта проблема удерживает нас от отправки нашего исправления ошибок iOS5 в App Store.