NavigationView — контейнерный компонент SwiftUI для организации стековой навигации между экранами. NavigationView создаёт навигационный стек с автоматической панелью, заголовком и кнопкой «Назад». Начиная с iOS 16, Apple рекомендует использовать NavigationStack. Подробнее читайте в документации Apple.
Главное
NavigationView — контейнер SwiftUI, который оборачивает иерархию экранов и предоставляет навигационный интерфейс. Внутри NavigationView работает NavigationLink — элемент, при нажатии на который текущий экран заменяется новым. NavigationView автоматически добавляет navigation bar с заголовком и кнопкой «Назад».
NavigationView появился в iOS 13 вместе с SwiftUI. Концептуально он заменяет UINavigationController из UIKit, но реализован декларативно. Вместо ручного push/pop разработчик описывает связь между экранами через NavigationLink. Система автоматически управляет стеком.
NavigationView поддерживает модификаторы .navigationTitle, .navigationBarTitleDisplayMode, .toolbar и .searchable. Для iOS 16+ Apple ввела NavigationStack, который сохраняет API NavigationView, но добавляет программное управление стеком через NavigationPath. Для проектов с поддержкой iOS 15 и ниже NavigationView остаётся единственным вариантом.
NavigationLink — элемент SwiftUI, создающий переход на целевой экран внутри NavigationView или NavigationStack. При нажатии на NavigationLink система добавляет целевой экран в стек навигации. Анимация перехода — стандартный push справа для iOS, адаптируется под платформу.
struct ContentView: View {
var body: some View {
NavigationView {
List(items) { item in
NavigationLink(destination: DetailView(item: item)) {
Text(item.title)
}
}
.navigationTitle("Список")
}
}
}
struct DetailView: View {
let item: Item
var body: some View {
VStack {
Text(item.description)
.navigationTitle(item.title)
.navigationBarTitleDisplayMode(.inline)
}
}
}NavigationLink принимает два параметра: destination — целевая View, и label — элемент, на который пользователь нажимает. Для списков удобен синтаксис с value и NavigationLink(value:), который автоматически дестектует ячейку и работает с NavigationPath.
С iOS 16 Apple представила NavigationStack как замену NavigationView. NavigationStack сохраняет декларативный синтаксис, но добавляет критически важную возможность — программное управление стеком через свойство path типа NavigationPath или массив Hashable.
| Возможность | NavigationView (iOS 13-15) | NavigationStack (iOS 16+) |
|---|---|---|
| Программный push | Нет, только через NavigationLink | Да, через path.append(value) |
| popToRoot | Только dismiss до root | path.removeLast(path.count) |
| Deep Links | Сложная реализация | Встроенная поддержка через path |
| Типизация стека | Нет (любая View в destination) | Да (массив Hashable значений) |
| SplitView iPad | ColumnStyle / StackStyle | NavigationSplitView (iOS 16+) |
Для проектов с минимальной версией iOS 16+ используйте NavigationStack. Для поддержки iOS 14-15 — NavigationView. NavigationStack не имеет прямых аналогов для старых версий, поэтому апгрейд требует проверки совместимости.
Модификаторы .toolbar и .navigationTitle управляют содержимым навигационной панели. .navigationTitle задаёт заголовок экрана, .navigationBarTitleDisplayMode выбирает стиль: .large (крупный, по умолчанию) или .inline (компактный, как в Settings). .toolbar добавляет кнопки, поиск и сегментированный контроль.
struct SettingsView: View {
var body: some View {
NavigationStack {
Form {
Section("Профиль") {
Text("Имя пользователя")
Toggle("Уведомления", isOn: $notifications)
}
}
.navigationTitle("Настройки")
.navigationBarTitleDisplayMode(.large)
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Сохранить") { save() }
}
ToolbarItem(placement: .navigationBarLeading) {
EditButton()
}
}
}
}
}.searchable — ещё один модификатор, интегрирующий строку поиска в navigation bar. Работает как с NavigationView, так и с NavigationStack. Поиск автоматически скрывается при скролле и показывается при свайпе вниз. Поддерживает фильтрацию списка через Binding String.
NavigationPath — тип iOS 16+, представляющий стек навигации как коллекцию значений Hashable. Разработчик добавляет элементы в path для программного перехода, удаляет для возврата. NavigationPath поддерживает глубокие ссылки, push-уведомления и восстановление состояния.
struct AppNavigation: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
List(categories) { category in
NavigationLink("Категория \(category.name)",
value: category)
}
.navigationTitle("Категории")
.navigationDestination(for: Category.self) { category in
ProductListView(category: category)
}
.navigationDestination(for: Product.self) { product in
ProductDetailView(product: product)
}
}
// Программный переход по deep link
.onOpenURL { url in
guard let productId = DeepLinkParser.parse(url) else { return }
path.append(Product(id: productId))
}
}
}.navigationDestination(for:) регистрирует тип данных, для которого нужно показать экран. Когда в path добавляется значение этого типа, система автоматически создаёт целевое View. Такой подход заменяет явный NavigationLink(destination:) и делает навигацию строго типизированной.
NavigationView и NavigationStack работают на всех платформах Apple: iOS, iPadOS, watchOS, tvOS и macOS. Поведение адаптируется под экран. На iPad NavigationStack поддерживает NavigationSplitView, который заменяет UISplitViewController из UIKit и отображает два столбца на широком экране.
NavigationSplitView (iOS 16+) разделяет экран на sidebar (список) и detail (детали). На iPhone sidebar скрывается, показывая только detail через NavigationLink. На iPad sidebar и detail отображаются одновременно в режиме split.
struct AdaptiveNavigation: View {
@State private var selectedCategory: Category?
var body: some View {
NavigationSplitView {
List(categories, selection: $selectedCategory) { category in
Text(category.name)
}
.navigationTitle("Категории")
} detail: {
ProductListView(category: selectedCategory)
}
}
}NavigationSplitView автоматически выбирает оптимальный режим отображения для каждого устройства. На iPhone в портрете — стек, на iPad и iPhone в landscape — split. Разработчику не нужно писать отдельный код для разных size classes.
Часто задаваемые вопросы
NavigationView — старый API (iOS 13-15), поддерживает только декларативные NavigationLink. NavigationStack — новый API (iOS 16+), добавляет path для программной навигации, глубокие ссылки и строго типизированный стек. NavigationStack рекомендован Apple для новых проектов.
Через модификатор .toolbar с ToolbarItem. Например: .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button('Настройки') { } } }. Placement определяет позицию: trailing (справа), leading (слева), principal (центр).
Заголовок задаётся через .navigationTitle('Название'). Стиль — .navigationBarTitleDisplayMode(.large) или .inline. Large — крупный заголовок в стиле iOS Music, inline — компактный, как в Settings. Стиль можно менять для каждого экрана отдельно.
Три способа: через value (NavigationLink(value:item) { Label }, iOS 16+), через destination + label, через isActive для программного перехода. NavigationLink с value чище для списков, так как не требует создания целевой View до перехода.
Да. NavigationView и NavigationStack доступны на iOS, iPadOS, watchOS, tvOS и macOS. На watchOS навигация использует иерархию интерфейса с колесом Digital Crown, на tvOS — фокусный ввод с пульта. Поведение адаптируется под платформу автоматически.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.