Yesterday

133. Чиним баг навигации в iOS 26

Недавно заметил в симуляторе iOS 26 сломавшуюся навигацию в нескольких экранах пет-проекта. Расскажу, в чем там было дело и как это исправляется.

Демонстрация проблемы

Баг №1: взаимодействие с menu закрывает экран
Баг №2: взаимодействие с confirmationDialog закрывает экран

Как должно быть

iOS 18.6, все работает корректно: и menu, и confirmationDialog
iOS 26, все работает корректно: и menu, и confirmationDialog (это видео записано после исправления "ошибки")

Причина неправильного поведения для пользователей с iOS 26

В проекте используется NavigationView, который все еще отлично работает сам по себе даже на iOS 26, а проблема возникает при отображении NavigationView внутри модального окна (sheet).

Варианты исправления

Вариант 1: самый быстрый и "очевидный"

Можно заменить в проекте все места, где используется NavigationView на NavigationStack ... и поднять минимальную версию iOS с 15 до 16. Таким образом можно сохранить исходное поведение и на старых версиях iOS, и на новых, но придется отказаться от пользователей на iOS 15*.

Вы можете справедливо заметить, что на iOS < 16 уже почти никого нет, и тем не менее там чуть больше 4% пользователей iPhone. Они не хотят или не могут обновиться, но ведь в нашем случае причина бага не в их девайсах, а где-то под капотом iOS 26, что вообще никак не касается других версий системы.

Вариант 2: менее быстрый

Можно сделать то же самое, что в варианте 1, но без поднятия минимальной версии iOS - достаточно сделать свою обертку для навигации, где внутри будет проверка на iOS 16: если возможно, используем NavigationStack, а если нет, то NavigationView.

Такой вариант я хотел применить еще на релизе iOS 18, но в то время это привело к крашам как раз в сценарии открытия NavigationStack внутри модального окна, причем именно на iOS 16+.

Вариант 3: поменять способ открытия родительского окна

Можно открывать экран с "площадкой" не в модальном окне, а в том же стеке навигации, что не требует изменения минимальной версии iOS и никаких проверок на версию iOS вообще не нужно добавлять, но немного поменяется подход к открытию некоторых экранов ... и все продолжит работать даже на iOS 26+, чудеса!

Что я сделаю

Скорее всего, буду выбирать между первыми двумя вариантами. Все же это нишевое приложение, и там очень мало пользователей, и даже если кто-то сидит в приложении на iOS 15, то все основные функции там останутся доступными еще очень долго, пока на сервере никаких глобальных изменений не сделают (а там очень редко что-то меняется).

Заключение

Жидкое стекло принесло нам немало багов, и в том числе задело исправно работавшую навигацию на старом добром NavigationView.

Главное, что все еще есть решения таких проблем, в том числе и обходные.