UITabBarController, MoreNavigationController и Святой Грааль вращения устройств

UPDATE: See my answer to this question first. This appears to be a bug. A minimal test case has been created and a report has been filed with Apple. (Fixed as of iPhone OS 3.1.)

Вот загадка из "Я так близко!" отдел.

У меня есть приложение для iPhone на панели вкладок. Каждая вкладка имеетUINavigationController с обычными подозреваемыми (навигационная панель, табличное представление ... которое в свою очередь может привести к другому VC, и т. д.).

Теперь один из этих низкоуровневых ВК должен использоваться вand ландшафтные режимы. Но есть проблема. Наши ландшафтно-ориентированные ВКshouldAutorotateToInterfaceOrientation: не будет вызвано "из коробки"! Что делать?

Вот что мы делаем. В моем контроллере панели вкладок, который я реализовал в своем собственном файле, у меня есть это:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
     return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}

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

Problem solved!!! Yay!

Что ж,not quite. :(

Похоже, что дела идут не так хорошо, когда мой дружественный к ландшафту VC вызывается из глубины контроллера панели вкладок.MoreNavigationController.

Я решил сравнить / сравнить VC, вызванный из одного изfirst four панель вкладокUINavigationControllers ... и тот же VC вызван изнутриMoreNavigationController, Это будет немного ультра-детально, так что терпите меня. Надеюсь, что игра за игрой окажется полезной для того, чтобы разоблачить вещи.

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

Правильно. Во-первых, давайте выберем один из первых четырех элементов панели вкладок и перейдем к нашему ВК.

Мы выберем третий элемент панели навигации, так что это третий контроллер навигации. Мы углубляемся в наш VC, который поддерживает вращение. Быстрая проверка подтверждает, что родитель действительно является третьим навигационным контроллером из списка контроллеров представления панели вкладок. Хорошо!

Давайте повернем устройство. Контроллеру панели вкладок предлагается выполнить автоматический поворот (см. Приведенный выше код). Мы наблюдаем, чтоselectedViewController Кроме того, третий навигационный контроллер, а также верхний и видимый контроллеры навигационного контроллера настроены на наш надежный виртуальный канал, который поддерживает вращение.

Таким образом, контроллер панели вкладок будет пересылатьshouldAutorotate сообщение третьему навигационному контроллеру ... но наш дружественный к ротации VC в конечном итоге получает сообщение. (Я не делаю здесь ничего особенного. Может быть, желаемый VC получает сообщение, потому что это верхний и / или видимый VC?) В любом случае, мы поворачиваемся к ландшафту, размер изменяется, и все хорошо. & quot; Большой успех! & quot;

Теперь нажмите эту кнопку «Назад» и вытолкните стек VC, оставив ландшафтный режим в процессе. Контроллер панели вкладок снова запрашивается.

Время немного в стороне здесь.topViewController для нашего контроллера Nav все еще этот VC дружественный к вращению, ноvisibleViewController теперь установленоUISnapshotModalViewController! Хех. Никогда не видел этого раньше ... ноЭрика Садун имеет, Похоже, что это "исчезающие контроллеры вида" (что в этом случае, безусловно, верно - оно исчезает в порядке).

Пока я продолжаю шагать, видимый VC остается в виде Snapshot, но верхний VC в конечном итоге переключается на следующий VC в стеке, поскольку мой специальный VC в конце концов исчез. Справедливо.

Такthat's сценарий, где все работает хорошо.

Теперь давайте попробуем тот же тест, только на этот раз мы пойдем кMoreNavigationController (элемент панели вкладок «Дополнительно») и перейдите к тому же классу VC, что и раньше. В моем случае это седьмой в списке VC контроллера панели вкладок.

Мы входим в VC с поддержкой ротации и ... на этот раз его просят повернутьdirectly! Контроллер панели вкладокnot попросил разрешения на поворот вообще. Хм.

Быстрая проверка родительского VC показывает, что этоMoreNavigationController, ОК, это имеет смысл.

Теперь попробуем повернуть устройство.NOTHING GETS CALLED, Ни одна из наших точек останова не пострадала. Не в нашем ВК. Нет в нашем контроллере панели вкладок. (А?!?!)

О-kaaaay. Давайте вытолкнем стек, вернемся в тот же VC и попробуем снова вращаться. Weird. ТЕПЕРЬ мы получаем вызов в контроллере панели вкладок с запросом разрешения на автоповорот. Здесь выбранный контроллер является нашим верным контроллером Nav (# 7), но на этот раз егоvisibleViewController а такжеtopViewController являютсяSET TO NIL!

Как только мы продолжим отсюда, на консоли отладчика появится загадочное сообщение:

Using two-stage rotation animation. To use the smoother single-stage animation, this application must remove two-stage method implementations.

Таинственный, потому чтоI'm not using two-stage rotation animation! нетSecondHalf варианты методов находятся в игре где-нибудь в моем исходном коде.

Увы, моему VC, поддерживающему ротацию, никогда не сообщают о том, что происходит ротация (даже если ротация происходит на экране), поэтому, конечно, в результате все мое представление искажается. Последуют беспредел и грусть. :(

На этом этапе мы даже не потрудимся вытолкнуть стек.

Я думаю, что документ View Controller намекает на возможную проблему:

If you want to perform custom animations during an orientation change, you can do so in one of two ways. Orientation changes used to occur in two steps, with notifications occurring at the beginning, middle, and end points of the rotation. However, in iPhone OS 3.0, support was added for performing orientation changes in one step. Using a one-step orientation change tends to be faster than the older two-step process and is generally recommended for any new code.

Интересно, еслиMoreNavigationController все еще реагирует на двухэтапный процесс, и, таким образом, вызывает какие-либо попытки использовать одношаговый процесс? Обратите внимание, что если вы отвечаете на двухэтапные сообщения, одноэтапный вариант не будет работать (опять же, в соответствии с документами). Я не отвечаю на них, но у меня есть скрытое подозрение, что что-то за кадром ЕСТЬ.

На самом деле, если я закомментирую одношаговый метод и попытаюсь ответить наwillAnimateSecondHalfOfRotationFromInterfaceOrientation:duration:Яdo получить памятку! Но он все еще не очень аккуратно высовывается из стека (с точки зрения визуальных эффектов). Даже незнакомецwillAnimateFirstHalfOfRotationFromInterfaceOrientation:duration: НЕ вызывается, даже когда я пытался скрыть вызов к себе (используя сообщение FirstHalf) вshouldAutorotateToInterfaceOrientation:, Он возвращается сразу во время трассировки, как будто я никогда не определял его. Вздох.

Так что это игра за игрой.

В итоге, имеетanyone успешно обработан одноэтапный поворот устройства для VC, вызванный из контроллера панели вкладок MoreNavigationController? Пытливые умы хотят знать!

Ответы на вопрос(3)

Ваш ответ на вопрос