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+
... немало условий, да? 😁