NavigationView: podstawy, stos nawigacji w aplikacjach SwiftUI

Autor: IT Sectr Opublikowano: 2026-02-22 Czas czytania: 6 min

NavigationView — komponent kontenerowy SwiftUI do organizacji nawigacji stosowej między ekranami. NavigationView tworzy stos nawigacyjny z automatycznym paskiem, tytułem i przyciskiem «Wstecz». Od iOS 16 Apple zaleca używanie NavigationStack. Więcej przeczytasz w dokumentacji Apple.

Najważniejsze

  • NavigationView — kontener SwiftUI do nawigacji stosowej, tworzy navigation bar i przycisk wstecz
  • NavigationLink — element przejścia do nowego ekranu wewnątrz NavigationView
  • NavigationStack — następca NavigationView (iOS 16+) z programowym zarządzaniem stosem
  • .toolbar — modyfikator do dodawania przycisków w navigation bar
  • .navigationTitle — ustawia tytuł ekranu w stylu large lub inline

Czym jest NavigationView?

NavigationView — kontener SwiftUI, który otacza hierarchię ekranów i udostępnia interfejs nawigacyjny. Wewnątrz NavigationView działa NavigationLink — element, po kliknięciu którego bieżący ekran jest zastępowany nowym. NavigationView automatycznie dodaje navigation bar z tytułem i przyciskiem «Wstecz».

NavigationView pojawił się w iOS 13 razem z SwiftUI. Koncepcyjnie zastępuje UINavigationController z UIKit, ale jest zaimplementowany deklaratywnie. Zamiast ręcznego push/pop programista opisuje połączenia między ekranami przez NavigationLink. System automatycznie zarządza stosem.

NavigationView obsługuje modyfikatory .navigationTitle, .navigationBarTitleDisplayMode, .toolbar i .searchable. Dla iOS 16+ Apple wprowadziła NavigationStack, który zachowuje API NavigationView, ale dodaje programowe zarządzanie stosem przez NavigationPath. Dla projektów wspierających iOS 15 i starsze NavigationView pozostaje jedyną opcją.

NavigationLink — element SwiftUI tworzący przejście do docelowego ekranu wewnątrz NavigationView lub NavigationStack. Po kliknięciu NavigationLink system dodaje docelowy ekran do stosu nawigacji. Animacja przejścia — standardowe push z prawej dla iOS, dostosowuje się do platformy.

swift
struct ContentView: View {
    var body: some View {
        NavigationView {
            List(items) { item in
                NavigationLink(destination: DetailView(item: item)) {
                    Text(item.title)
                }
            }
            .navigationTitle("Lista")
        }
    }
}

struct DetailView: View {
    let item: Item

    var body: some View {
        VStack {
            Text(item.description)
                .navigationTitle(item.title)
                .navigationBarTitleDisplayMode(.inline)
        }
    }
}

NavigationLink przyjmuje dwa parametry: destination — docelowy widok, oraz label — element, na który użytkownik klika. Dla list wygodny jest składnia z value i NavigationLink(value:), który automatycznie odznacza komórkę i współpracuje z NavigationPath.

Od iOS 16 Apple przedstawiła NavigationStack jako zamiennik NavigationView. NavigationStack zachowuje deklaratywną składnię, ale dodaje krytycznie ważną możliwość — programowe zarządzanie stosem przez właściwość path typu NavigationPath lub tablicy Hashable.

MożliwośćNavigationView (iOS 13-15)NavigationStack (iOS 16+)
Programowy pushNie, tylko przez NavigationLinkTak, przez path.append(value)
popToRootTylko dismiss do rootpath.removeLast(path.count)
Deep LinksSkomplikowana implementacjaWbudowane wsparcie przez path
Typizacja stosuNie (dowolny View w destination)Tak (tablica wartości Hashable)
SplitView iPadColumnStyle / StackStyleNavigationSplitView (iOS 16+)

Dla projektów z minimalną wersją iOS 16+ używaj NavigationStack. Dla wsparcia iOS 14-15 — NavigationView. NavigationStack nie ma bezpośrednich odpowiedników dla starych wersji, więc aktualizacja wymaga sprawdzenia kompatybilności.

Toolbar i konfiguracja navigationTitle

Modyfikatory .toolbar i .navigationTitle zarządzają zawartością paska nawigacyjnego. .navigationTitle ustawia tytuł ekranu, .navigationBarTitleDisplayMode wybiera styl: .large (duży, domyślnie) lub .inline (kompaktowy, jak w Ustawieniach). .toolbar dodaje przyciski, wyszukiwanie i kontrolę segmentową.

swift
struct SettingsView: View {
    var body: some View {
        NavigationStack {
            Form {
                Section("Profil") {
                    Text("Nazwa użytkownika")
                    Toggle("Powiadomienia", isOn: $notifications)
                }
            }
            .navigationTitle("Ustawienia")
            .navigationBarTitleDisplayMode(.large)
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Zapisz") { save() }
                }
                ToolbarItem(placement: .navigationBarLeading) {
                    EditButton()
                }
            }
        }
    }
}

.searchable — kolejny modyfikator, integrujący pasek wyszukiwania z navigation bar. Działa zarówno z NavigationView, jak i NavigationStack. Wyszukiwanie automatycznie ukrywa się podczas przewijania i pokazuje przy przesunięciu w dół. Obsługuje filtrowanie listy przez Binding String.

Programowa nawigacja z NavigationPath

NavigationPath — typ iOS 16+, reprezentujący stos nawigacji jako kolekcję wartości Hashable. Programista dodaje elementy do path dla programowego przejścia, usuwa dla powrotu. NavigationPath obsługuje głębokie linki, powiadomienia push i przywracanie stanu.

swift
struct AppNavigation: View {
    @State private var path = NavigationPath()

    var body: some View {
        NavigationStack(path: $path) {
            List(categories) { category in
                NavigationLink("Kategoria \(category.name)",
                               value: category)
            }
            .navigationTitle("Kategorie")
            .navigationDestination(for: Category.self) { category in
                ProductListView(category: category)
            }
            .navigationDestination(for: Product.self) { product in
                ProductDetailView(product: product)
            }
        }

        // Programistyczne przejście przez deep link
        .onOpenURL { url in
            guard let productId = DeepLinkParser.parse(url) else { return }
            path.append(Product(id: productId))
        }
    }
}

.navigationDestination(for:) rejestruje typ danych, dla którego ma być pokazany ekran. Gdy do path dodawana jest wartość tego typu, system automatycznie tworzy docelowy widok. Takie podejście zastępuje jawny NavigationLink(destination:) i czyni nawigację ściśle typowaną.

NavigationView i NavigationStack działają na wszystkich platformach Apple: iOS, iPadOS, watchOS, tvOS i macOS. Zachowanie dostosowuje się do ekranu. Na iPad NavigationStack obsługuje NavigationSplitView, który zastępuje UISplitViewController z UIKit i wyświetla dwie kolumny na szerokim ekranie.

NavigationSplitView (iOS 16+) dzieli ekran na sidebar (lista) i detail (szczegóły). Na iPhone sidebar jest ukryty, pokazując tylko detail przez NavigationLink. Na iPad sidebar i detail są wyświetlane jednocześnie w trybie 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("Kategorie")
        } detail: {
            ProductListView(category: selectedCategory)
        }
    }
}

NavigationSplitView automatycznie wybiera optymalny tryb wyświetlania dla każdego urządzenia. Na iPhone w trybie portretowym — stos, na iPad i iPhone w landscape — split. Programista nie musi pisać osobnego kodu dla różnych size classes.

Często zadawane pytania

Jaka jest różnica między NavigationView a NavigationStack?

NavigationView — stare API (iOS 13-15), obsługuje tylko deklaratywne NavigationLink. NavigationStack — nowe API (iOS 16+), dodaje path dla programowej nawigacji, głębokie linki i ściśle typowany stos. NavigationStack jest zalecany przez Apple dla nowych projektów.

Jak dodać przycisk w navigationBar?

Przez modyfikator .toolbar z ToolbarItem. Na przykład: .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button('Ustawienia') { } } }. Placement określa pozycję: trailing (po prawej), leading (po lewej), principal (środek).

Jak skonfigurować tytuł i jego styl?

Tytuł ustawia się przez .navigationTitle('Nazwa'). Styl — .navigationBarTitleDisplayMode(.large) lub .inline. Large — duży tytuł w stylu iOS Music, inline — kompaktowy, jak w Ustawieniach. Styl można zmieniać dla każdego ekranu osobno.

Jak przekazać dane przez NavigationLink?

Trzy sposoby: przez value (NavigationLink(value:item) { Label }, iOS 16+), przez destination + label, przez isActive dla programowego przejścia. NavigationLink z value jest czystszy dla list, ponieważ nie wymaga tworzenia docelowego widoku przed przejściem.

Czy można używać NavigationView na watchOS i tvOS?

Tak. NavigationView i NavigationStack są dostępne na iOS, iPadOS, watchOS, tvOS i macOS. Na watchOS nawigacja używa hierarchii interfejsu z kołem Digital Crown, na tvOS — nawigacja fokusowa z pilota. Zachowanie dostosowuje się do platformy automatycznie.

Podsumowanie

  • NavigationView — kontener SwiftUI do nawigacji stosowej z automatycznym navigation bar i przyciskiem «Wstecz»
  • NavigationLink — główny element przejścia, obsługuje składnię deklaratywną (destination) i value-based
  • NavigationStack (iOS 16+) zastępuje NavigationView, dodając programowe zarządzanie stosem przez NavigationPath
  • .toolbar dodaje przyciski w navigation bar, .navigationTitle ustawia tytuł z wyborem stylu large/inline
  • NavigationPath — ściśle typowany stos wartości Hashable dla programowej nawigacji i deep links
  • NavigationSplitView (iOS 16+) dostosowuje interfejs do iPad i iPhone, automatycznie wybierając split lub stos
  • Wybór między NavigationView a NavigationStack zależy od minimalnej wspieranej wersji iOS w projekcie

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również