NavigationView: основы, стек навигации в SwiftUI приложениях

Автор: IT Sectr Опубликовано: 2026-02-22 Время чтения: 6 мин

NavigationView — контейнерный компонент SwiftUI для организации стековой навигации между экранами. NavigationView создаёт навигационный стек с автоматической панелью, заголовком и кнопкой «Назад». Начиная с iOS 16, Apple рекомендует использовать NavigationStack. Подробнее читайте в документации Apple.

Главное

  • NavigationView — контейнер SwiftUI для стековой навигации, создаёт navigation bar и back button
  • NavigationLink — элемент перехода на новый экран внутри NavigationView
  • NavigationStack — преемник NavigationView (iOS 16+) с программным управлением стеком
  • .toolbar — модификатор для добавления кнопок в navigation bar
  • .navigationTitle — задаёт заголовок экрана в стиле large или inline

Что такое NavigationView?

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, адаптируется под платформу.

swift
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 до rootpath.removeLast(path.count)
Deep LinksСложная реализацияВстроенная поддержка через path
Типизация стекаНет (любая View в destination)Да (массив Hashable значений)
SplitView iPadColumnStyle / StackStyleNavigationSplitView (iOS 16+)

Для проектов с минимальной версией iOS 16+ используйте NavigationStack. Для поддержки iOS 14-15 — NavigationView. NavigationStack не имеет прямых аналогов для старых версий, поэтому апгрейд требует проверки совместимости.

Toolbar и настройка navigationTitle

Модификаторы .toolbar и .navigationTitle управляют содержимым навигационной панели. .navigationTitle задаёт заголовок экрана, .navigationBarTitleDisplayMode выбирает стиль: .large (крупный, по умолчанию) или .inline (компактный, как в Settings). .toolbar добавляет кнопки, поиск и сегментированный контроль.

swift
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

NavigationPath — тип iOS 16+, представляющий стек навигации как коллекцию значений Hashable. Разработчик добавляет элементы в path для программного перехода, удаляет для возврата. NavigationPath поддерживает глубокие ссылки, push-уведомления и восстановление состояния.

swift
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.

swift
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 и NavigationStack?

NavigationView — старый API (iOS 13-15), поддерживает только декларативные NavigationLink. NavigationStack — новый API (iOS 16+), добавляет path для программной навигации, глубокие ссылки и строго типизированный стек. NavigationStack рекомендован Apple для новых проектов.

Как добавить кнопку в navigationBar?

Через модификатор .toolbar с ToolbarItem. Например: .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button('Настройки') { } } }. Placement определяет позицию: trailing (справа), leading (слева), principal (центр).

Как настроить заголовок и его стиль?

Заголовок задаётся через .navigationTitle('Название'). Стиль — .navigationBarTitleDisplayMode(.large) или .inline. Large — крупный заголовок в стиле iOS Music, inline — компактный, как в Settings. Стиль можно менять для каждого экрана отдельно.

Как передать данные через NavigationLink?

Три способа: через value (NavigationLink(value:item) { Label }, iOS 16+), через destination + label, через isActive для программного перехода. NavigationLink с value чище для списков, так как не требует создания целевой View до перехода.

Можно ли использовать NavigationView на watchOS и tvOS?

Да. NavigationView и NavigationStack доступны на iOS, iPadOS, watchOS, tvOS и macOS. На watchOS навигация использует иерархию интерфейса с колесом Digital Crown, на tvOS — фокусный ввод с пульта. Поведение адаптируется под платформу автоматически.

Итоги

  • NavigationView — контейнер SwiftUI для стековой навигации с автоматическим navigation bar и кнопкой «Назад»
  • NavigationLink — основной элемент перехода, поддерживает декларативный (destination) и value-based синтаксис
  • NavigationStack (iOS 16+) заменяет NavigationView, добавляя программное управление стеком через NavigationPath
  • .toolbar добавляет кнопки в navigation bar, .navigationTitle задаёт заголовок с выбором стиля large/inline
  • NavigationPath — строго типизированный стек значений Hashable для программной навигации и deep links
  • NavigationSplitView (iOS 16+) адаптирует интерфейс под iPad и iPhone, автоматически выбирая split или стек
  • Выбор между NavigationView и NavigationStack определяется минимальной поддерживаемой версией iOS в проекте

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также