Это руководство описывает пошаговый процесс внедрения адаптивного интерфейса на базе NavigationSplitView для приложений под macOS, iPadOS и iOS. Оно основано на рабочем примере из этого репозитория и показывает, как организовать данные, состояние и пользовательские представления, чтобы добиться одинаково предсказуемого поведения на разных платформах и при разных size class.
- Создайте типы, которые поддерживают протоколы
IdentifiableиHashable, чтобы их можно было безопасно использовать в списках и навигации. - В примере используется структура
CustomColor, описывающая элемент каталога цветов, и структураCustomColorCategory, группирующая цвета по категориям.【F:XcodeProject/NewNav/DTO/CustomColor.swift†L1-L15】【F:XcodeProject/NewNav/DTO/CustomColorCategory.swift†L1-L8】 - Организуйте источник данных (например, синглтон, сервис или репозиторий), который возвращает список категорий с вложенными элементами. В демо проекте это упрощённый объект
Dataс предзаполненными категориями.【F:XcodeProject/NewNav/ContentView.swift†L1-L20】
- В корневом
ContentViewхраните текущее состояние выбора категории и элемента, путь навигации (если нужно поддерживать глубокие переходы) и видимость дополнительных панелей интерфейса. - Для адаптации к размеру экрана запросите
horizontalSizeClassчерез@Environmentи храните выбранную конфигурацию столбцов в@StateпараметреcolumnVisibility. - Базовый набор состояний показан в примере:
selectedCategory,selectedColor,columnVisibility,pathCategory,pathColorиshowInspector.【F:XcodeProject/NewNav/ContentView.swift†L22-L31】
- Оберните основной контент в
NavigationSplitView, передав биндинг кcolumnVisibility, чтобы управлять числом отображаемых столбцов (например, двойной или тройной режим). - Реализуйте три секции: «Sidebar» (первый блок), «Content» (второй блок) и «Detail» (третий блок).
- Sidebar:
ListсNavigationLink, использующаяselectionдля поддержки синхронизации выбранного объекта иnavigationTitleдля локализации заголовка.【F:XcodeProject/NewNav/ContentView.swift†L33-L40】 - Content: отдельное представление
CategoryView, отвечающее за показ элементов выбранной категории.【F:XcodeProject/NewNav/ContentView.swift†L40-L45】 - Detail: представление
DetailView, которое отображает подробности по текущему элементу (или плейсхолдер, если элемент не выбран).【F:XcodeProject/NewNav/ContentView.swift†L45-L49】
- Sidebar:
- Примените
.navigationSplitViewStyle(.automatic), чтобы предоставить системе решать, как компоновать столбцы на разных устройствах.【F:XcodeProject/NewNav/ContentView.swift†L49-L50】
- Создайте вспомогательный контейнер, который меняет разметку в зависимости от
horizontalSizeClass. В примере используетсяSizeClassAdaptiveView, который выводит разные представления для regular/compact режимов.【F:XcodeProject/NewNav/SizeClassAdaptiveView.swift†L1-L24】 - В
CategoryViewпримените этот контейнер: для regular режима оставляйте список цветов, а в compact режиме добавляйте навигационные переходы (navigationDestination) для отображения деталей в стековом интерфейсе.【F:XcodeProject/NewNav/CategoryView.swift†L8-L23】 - Используйте
navigationTitle, чтобы синхронизировать заголовок в средней колонке или в стеке навигации.【F:XcodeProject/NewNav/CategoryView.swift†L21-L22】
DetailViewдолжен принимать биндинг к выбранному элементу и отображать его содержимое. При отсутствии выбора выводите плейсхолдер (например,ColorPlaceholder).【F:XcodeProject/NewNav/DetailView.swift†L1-L20】【F:XcodeProject/NewNav/InspectorPanel.swift†L1-L21】- Если требуется боковая панель инспектора, добавьте
.inspector(isPresented:)кNavigationSplitViewи передайте туда отдельное представление (например,InspectorPanel).【F:XcodeProject/NewNav/ContentView.swift†L50-L52】【F:XcodeProject/NewNav/InspectorPanel.swift†L23-L71】
- Используйте
.onAppear, чтобы настроить начальное состояние компонентов в зависимости от size class (например, сразу показывать инспектор в regular режиме).【F:XcodeProject/NewNav/ContentView.swift†L53-L57】 - Отслеживайте изменения выбранной категории и обновляйте связанный элемент. В compact режиме обнуляйте выбор, чтобы не перескакивать на третий экран без участия пользователя.【F:XcodeProject/NewNav/ContentView.swift†L58-L65】
- Подписывайтесь на изменения
horizontalSizeClass, чтобы динамически менять состояние интерфейса (например, скрывать инспектор в compact режиме).【F:XcodeProject/NewNav/ContentView.swift†L65-L71】
- В существующем проекте добавьте файлы, описанные выше, или адаптируйте собственные модели/представления под те же требования (
Identifiable,Hashable,@State/@Binding). - Подключите
NavigationSplitViewв корневой точке (например, внутриWindowGroup) и передайте в него данные приложения. - Настройте дополнительные панели (инспекторы, футеры и т. д.) при помощи соответствующих модификаторов SwiftUI.
- Проверьте работу на целевых платформах в Xcode Previews и на устройстве/симуляторе, обращая внимание на переключение между compact/regular режимами и глубину навигации.
- Для macOS и iPadOS важно настроить
columnVisibility, чтобы пользователь мог управлять отображением колонок вручную. - Если требуется программно открыть/закрыть определённую колонку, используйте
NavigationSplitViewVisibilityи обновляйте его состояние в ответ на пользовательские действия. - Используйте
NavigationPath, когда нужно поддерживать сложную иерархию переходов или deep-linking; в простых сценариях достаточноselection. - В compact интерфейсе избегайте автоматического выбора элементов, чтобы не скрывать пользовательский список после загрузки.
- Для тестирования отображения инспектора на iPad и Mac используйте модификатор
.inspector, который появится только при достаточной ширине окна или в соответствии с настройками платформы.
Следуя этим шагам, вы сможете быстро интегрировать NavigationSplitView в любое приложение и обеспечить правильную работу навигации на всех поддерживаемых платформах.