Раньше представление «основной-подробный» со стеком навигации реализовывалось с помощью UISplitViewController с двумя контроллерами навигации.
В компактной компоновке эти 2 контроллера волшебным образом «сворачиваются» в один с помощью UISplitViewController, и мы можем сформировать базовый стек навигации: мастер -> деталь -> поддеталь -> подподробность.
Эта настройка работала задолго до iOS 26.
В iOS 26 push-переход навигации работает с ошибками на подуровнях из-за двух отдельных проблем с макетом:
Когда переход начинается, макет контроллера принудительного представления не обновляется. Начальный размер (до обновления) — .ноль, и в результате мы видим, как он анимируется до окончательного размера и положения. Посмотрите, как при записи экрана синий вид расширяется с нуля.
Когда начинается переход, руководство по расположению безопасной зоны не обновляется. Начальный размер безопасной области равен нулю. Если на него опирается макет контроллера представления, мы видим, как он анимируется, чтобы соответствовать размеру и положению безопасной области. Посмотрите, как при записи экрана розовый вид уменьшается по сравнению с полноэкранным размером.
Эта анимация не ожидается! Макет контроллера принудительного представления должен быть исправлен ограничениями во время принудительного перехода (как это было до iOS 26).
Ошибку (1) можно обойти, добавив вызов LayoutIfNeeded() внутри viewDidLoad() (см. SubSubDetailViewController ниже).
Но (2) сложно обойти.
Что пробовали:
Замените настройку viewControllers на более новый API iOS 14, это не дало эффекта — те же ошибки:
Используйте один UINavigationController, разворачивая либо MasterViewController, либо DetailViewController от наличия UINavigationController. Это приводит к нежелательным последствиям в некомпактном режиме «основной-подробный» (отображается на iPad и больших iPhone).
Использование верхнего ограничения, связанного с нижней привязкой панели навигации, вместо SafeAreaLayoutGuide не учитывает области вырезов на левом и правом краях (на телефонах с альбомной ориентацией).
Наличие одной специальной версии кода на маленьких iPhone и другой версии кода на других устройствах на модели устройства нежелательно, поскольку многозадачность iPad может использоваться для динамического переключения в режим компактной компоновки.
Чтобы воспроизвести, создайте проект iOS в Xcode 26, вставьте этот код и запустите на небольшом симуляторе iPhone iOS 26.0:
Раньше представление «основной-подробный» со стеком навигации реализовывалось с помощью UISplitViewController с двумя контроллерами навигации. В компактной компоновке эти 2 контроллера волшебным образом «сворачиваются» в один с помощью UISplitViewController, и мы можем сформировать базовый стек навигации: мастер -> деталь -> поддеталь -> подподробность. Эта настройка работала задолго до iOS 26. В iOS 26 push-переход навигации работает с ошибками на подуровнях из-за двух отдельных проблем с макетом: [list] [*]Когда переход начинается, макет контроллера принудительного представления не обновляется. Начальный размер (до обновления) — .ноль, и в результате мы видим, как он анимируется до окончательного размера и положения. Посмотрите, как при записи экрана синий вид расширяется с нуля. [*]Когда начинается переход, руководство по расположению безопасной зоны не обновляется. Начальный размер безопасной области равен нулю. Если на него опирается макет контроллера представления, мы видим, как он анимируется, чтобы соответствовать размеру и положению безопасной области. Посмотрите, как при записи экрана розовый вид уменьшается по сравнению с полноэкранным размером. [/list] Эта анимация не ожидается! Макет контроллера принудительного представления должен быть исправлен ограничениями во время принудительного перехода (как это было до iOS 26). Ошибку (1) можно обойти, добавив вызов LayoutIfNeeded() внутри viewDidLoad() (см. SubSubDetailViewController ниже). Но (2) сложно обойти. Что пробовали: [list] [*]Замените настройку viewControllers на более новый API iOS 14, это не дало эффекта — те же ошибки: [code]super.init(style: .doubleColumn) self.setViewController(MasterViewController(), for: .primary) self.setViewController(DetailViewController(), for: .secondary) [/code]
[*]Используйте один UINavigationController, разворачивая либо MasterViewController, либо DetailViewController от наличия UINavigationController. Это приводит к нежелательным последствиям в некомпактном режиме «основной-подробный» (отображается на iPad и больших iPhone).
[*]Использование верхнего ограничения, связанного с нижней привязкой панели навигации, вместо SafeAreaLayoutGuide не учитывает области вырезов на левом и правом краях (на телефонах с альбомной ориентацией).
[*]Наличие одной специальной версии кода на маленьких iPhone и другой версии кода на других устройствах на модели устройства нежелательно, поскольку многозадачность iPad может использоваться для динамического переключения в режим компактной компоновки.
[/list] Чтобы воспроизвести, создайте проект iOS в Xcode 26, вставьте этот код и запустите на небольшом симуляторе iPhone iOS 26.0: [code]import UIKit