124. Адаптируем NavigationSplitView
В iOS 16 добавили NavigationSplitView, чтобы можно было расположить контент в 2 или 3 колонки. В этой мини-статье расскажу основные моменты по адаптации этой штуки в приложении для iOS, чтобы ничего не сломалось.
Вводные
Возьмем iOS-приложение, в котором навигация построена на NavigationStack, т.е. можно ходить по экранам вперед/назад стандартными способами и с помощью navigationDestination. Кстати, подобное приложение я уже показывал в статье 43.
Задача в том, чтобы сохранить внешний вид и поведение приложения на айфоне при переходе с NavigationStack на NavigationSplitView. в приложении со списками (необязательно List, просто любой вертикальный контент в скролле с кнопками для перехода на следующий экран).
Для краткости буду называть NavigationStack просто NS, а NavigationSplitView - NSV.
Важно помнить, что NSV по умолчанию будет показывать все свои столбцы не только на айпаде, но и в том числе на айфонах pro max и plus в ландшафтном режиме.
Основные компоненты
NSV предлагает нам до трех столбцов: sidebar, content, detail. Вот этот инициализатор для примера:
init(
@ViewBuilder sidebar: () -> Sidebar,
@ViewBuilder content: () -> Content,
@ViewBuilder detail: () -> Detail
)
Официальная документация в этом случае меня не порадовала, вот пример описания этих столбцов (на русском для удобства):
sidebar- вьюха для отображения колонки слеваcontent- вьюха для отображения колонки по центруdetail- вьюха для отображения зоны с детализацией
Дальше будет мое описание, полученное на личном опыте 😁
Sidebar
Именно эта вьюха отображается по умолчанию на айфоне при использовании NS - с нее можно перейти на следующий экран через push (navigationLink).
То есть при замене NS на NSV в нашем приложении именно в sidebar нужно поместить весь контент корневого экрана навигации, который мы хотим видеть на айфоне при отображении условного списка элементов.
Ширину этой вьюхи на айпаде можно настроить модификатором navigationSplitViewColumnWidth, у которого есть 2 версии: первая для конкретной ширины, вторая для нескольких вариантов.
Content
Эта вьюха вряд ли пригодится большинству приложений: она служит первым уровнем детального контента, который можно увидеть при нажатии на элемент списка в sidebar на айпаде, т.е. подойдет для какой-нибудь подкатегории, например.
На айфоне именно тут будут открываться экраны через navigationLink с главного списка, что будет выглядеть нормально (как всегда) в портретном режиме, а вот если приложение поддерживает ландшафтный режим, то все будет выглядеть совсем не как обычно, а прямо как на айпаде - в три столбца.
Detail
Если явно не указать content (из предыдущего раздела статьи) для NSV, то именно в detail будет отображаться экран, открытый через navigationLink (и на айфоне, и на айпаде) в любом режиме (портретный/ландшафтный).
Другие инициализаторы
У NSV есть несколько других инициализаторов, которые могут пригодиться в отдельных случаях - все их можно найти в документации.
Например, можно настроить columnVisibility, чтобы при повороте экрана (меняется horizontalSizeClass) изменять и видимость колонок:
@Environment(\.horizontalSizeClass) var horizontalSizeClass @State private var columnVisibility = NavigationSplitViewVisibility.automatic // и потом где-нибудь в onChange(of: ...) columnVisibility = horizontalSizeClass == .regular && isEmpty ? .detailOnly : .automatic
Заключение
NavigationSplitView прикольный инструмент для быстрой адаптации приложения под айпад, но только если ваше приложение будет нормально выглядеть и работать с такой навигацией.
Настройки есть, но как и в случае с привычной навигацией для айфона - не особо разнообразные. Если ваше приложение поддерживает айпад, структура навигации напоминает то, что показывают в официальной документации, и вы поддерживаете iOS 16+ ... немало условий, да? 😁