Push Presentation — wzorzec nawigacji w aplikacjach mobilnych, w którym każdy nowy ekran jest dodawany na szczyt stosu nawigacyjnego nad poprzednim. Użytkownik może kolejno przechodzić do przodu przez treść i wracać za pomocą przycisku systemowego lub przesunięcia. Według Apple Developer, 2025, UINavigationController jest używany w 85% aplikacji iOS jako podstawowy wzorzec nawigacyjny. W Android podobna funkcjonalność jest realizowana przez FragmentManager i NavController z Navigation Component.
Najważniejsze
Push Presentation — to mechanizm nawigacji, w którym każdy nowy ekran jest umieszczany na szczycie stosu, a poprzedni ekran pozostaje w pamięci pod nim. Użytkownik zagłębia się w treść, kolejno otwierając szczegółowe ekrany, a przycisk wstecz zwraca go do poprzedniego kroku.
Architektura nawigacji Push opiera się na strukturze danych LIFO (Last In, First Out). Nowy ekran jest zawsze dodawany na koniec stosu, a usuwanie następuje tylko ze szczytu. Gwarantuje to przewidywalne zachowanie: użytkownik zawsze wie, że przycisk wstecz wróci go dokładnie o jeden krok wstecz. Stos nawigacyjny może zawierać od 2 do 10+ ekranów w zależności od złożoności aplikacji.
Push Presentation to podstawowy wzorzec w aplikacjach z treścią hierarchiczną: kanały informacyjne, katalogi produktów, menu wielopoziomowe i dokumentacja. Według Material Design, nawigacja stosowa jest odpowiednia dla scenariuszy, w których użytkownik eksploruje treść od ogółu do szczegółu, a każdy kolejny ekran pogłębia zrozumienie tematu.
Stos nawigacyjny — to uporządkowany zbiór ekranów, w którym każdy element przechowuje stan swojego ViewController lub Fragment. Podczas operacji Push nowy ekran jest dodawany do stosu, jego wyświetlanie jest animowane (slajd z prawej w iOS, slajd z dołu lub Fade w Android) i staje się aktywny.
Podczas operacji Pop (naciśnięcie wstecz) górny ekran jest usuwany ze stosu, niszczony lub przechodzi do pamięci, a poprzedni ekran staje się aktywny. iOS domyślnie niszczy popped ViewController, zwalniając pamięć. Android może zachować Fragment w back stack z możliwością przywrócenia bez ponownego tworzenia.
Głębokość stosu wpływa na wydajność: każdy ekran w stosie zużywa pamięć. Zaleca się nie przechowywać więcej niż 10 ekranów w stosie. Do głębokiej nawigacji używaj PopToRoot lub restartu stosu z nowym ekranem głównym. Navigation Component w Android automatycznie zarządza stanem stosu przez SavedStateHandle.
UINavigationController — kontroler kontenerowy iOS zarządzający stosem UIViewController. Automatycznie wyświetla pasek nawigacyjny (navigation bar) z tytułem bieżącego ekranu i przyciskiem powrotu. Domyślna animacja Push — slajd od prawej do lewej, tworząca u użytkownika wrażenie zagłębiania się w treść.
Dodawanie ekranu odbywa się przez pushViewController(_:animated:). Usuwanie — przez popViewController(animated:). Aby wrócić do ekranu głównego, używa się popToRootViewController(animated:). UINavigationController obsługuje również programowe zarządzanie stosem przez właściwość viewControllers — tablicę wszystkich kontrolerów w stosie.
Pasek nawigacyjny zawiera tytuł ekranu (title), przycisk wstecz i opcjonalne przyciski akcji. Od iOS 11, Large Titles (prefersLargeTitles) umożliwiają wyświetlanie tytułu powiększoną czcionką, która animacyjnie zmniejsza się podczas przewijania. Poprawia to hierarchię nawigacyjną i informuje użytkownika o bieżącej sekcji.
let detailVC = DetailViewController()
detailVC.title = "Item Details"
navigationController?.pushViewController(detailVC, animated: true)
// Powrót do poprzedniego ekranu
navigationController?.popViewController(animated: true)
// Powrót do głównego ekranu
navigationController?.popToRootViewController(animated: true)
Navigation Component — biblioteka Android Jetpack do deklaratywnej nawigacji. Zapewnia NavController, który zarządza fragmentami lub ekranami Compose przez graf nawigacji (nav_graph). Push w Android jest analogiczny do iOS: każdy nowy Fragment jest dodawany do back stack, a przycisk wstecz przywraca poprzedni.
NavHost — kontener wyświetlający bieżący cel z NavGraph. NavGraph — plik XML opisujący wszystkie ekrany aplikacji i połączenia między nimi. Przejścia są definiowane przez actions z określeniem destination i opcjonalnych argumentów. Navigation Component automatycznie obsługuje systemowy przycisk wstecz, animacje i zapisywanie stanu.
Do przesyłania danych między ekranami Navigation Component obsługuje Safe Args — generowanie kodu type-safe klas argumentów. Zamiast ręcznego umieszczania danych w Bundle, programista deklaruje argumenty w NavGraph i otrzymuje je przez wygenerowane klasy Directions i Args. Safe Args eliminuje błędy niezgodności typów i upraszcza refaktoryzację.
// Definicja NavGraph w XML
<!-- res/navigation/nav_graph.xml -->
@navigation {
NavHost(startDestination = "list") {
composable("list") { ListScreen() }
composable(
"detail/{itemId}",
arguments = listOf(navArgument("itemId") { type = NavType.IntType })
) { DetailScreen(it.arguments()?.getInt("itemId") ?: 0) }
}
}
// Nawiguj programowo
navController.navigate("detail/42")
Połączenie Bottom Navigation i nawigacji Push — częsty wzorzec w aplikacjach mobilnych. Każda zakładka Bottom Navigation ma własny stos ekranów. Navigation Component obsługuje to przez NavHost per tab lub jeden NavHost z osobnymi grafami dla każdej zakładki. Przełączanie zakładek nie resetuje stanu stosów Push.
Push Presentation i Modal Presentation rozwiązują różne zadania nawigacji. Push jest przeznaczony do sekwencyjnego przeglądania treści, gdzie każdy nowy ekran pogłębia kontekst. Modal — do zadań wymagających skupienia i zakończenia. W praktyce ważne jest wybranie odpowiedniego wzorca dla konkretnego scenariusza.
Główne kryteria wyboru: jeśli użytkownik powinien swobodnie wracać bez utraty kontekstu — wybierz Push. Jeśli zadanie jest tymczasowe i blokuje główną treść (formularz, autoryzacja) — użyj Modal. Mieszanie wzorców na jednym ekranie (Push wewnątrz Modal) jest dopuszczalne, ale wymaga jasnej hierarchii wizualnej.
Błędem jest używanie Modal dla sekwencji ekranów, które logicznie są częścią głównego przepływu. Na przykład kreator tworzenia zamówienia (Krok 1 → Krok 2 → Krok 3) lepiej zrealizować przez Push wewnątrz kontenera modalnego, a nie przez łańcuch okien modalnych. Zachowuje to hierarchię nawigacyjną i przewidywalność powrotu.
Rozważmy pełną implementację nawigacji Push na obu platformach. Przykład w Swift demonstruje UINavigationController z programowym zarządzaniem stosem i obsługą głębokich linków. Przykład w Kotlin pokazuje Navigation Component z NavHost, argumentami i animacjami.
class ListViewController: UIViewController {
func showDetail(_ itemId: Int) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let detailVC = storyboard.instantiateViewController(
withIdentifier: "DetailViewController"
) as! DetailViewController
detailVC.itemId = itemId
navigationController?.pushViewController(detailVC, animated: true)
}
}
class DetailViewController: UIViewController {
var itemId: Int = 0
override func viewDidLoad() {
super.viewDidLoad()
title = "Item #\(itemId)"
}
}
@Composable
fun PushNavigationApp() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "list") {
composable("list") {
ListScreen(
onItemClick = { id -> navController.navigate("detail/$id") }
)
}
composable(
"detail/{itemId}",
arguments = listOf(navArgument("itemId") { type = NavType.IntType })
) { backStackEntry ->
val itemId = backStackEntry.arguments()?.getInt("itemId") ?: 0
DetailScreen(itemId = itemId, onBack = { navController.popBackStack() })
}
}
}
Przykłady pokazują podstawową nawigację Push: lista → szczegóły. iOS używa storyboardów i UINavigationController z ręcznym przesyłaniem danych. Android używa NavHost z type-safe argumentami i automatycznym zarządzaniem back stack. Oba podejścia obsługują głębokie linki, niestandardowe animacje i zapisywanie stanu przy obrocie.
Często zadawane pytania
Push dodaje ekran do stosu UINavigationController z przyciskiem powrotu. Present otwiera okno modalne bez przycisku wstecz — użytkownik musi je jawnie zamknąć. Push nadaje się do treści sekwencyjnej, Present — do zadań wymagających skupienia. W SwiftUI Push odpowiada NavigationLink, a Present — .sheet.
Navigation Component udostępnia metody popBackStack do określonego punktu oraz popUpTo do czyszczenia stosu. Aby zapobiec przepełnieniu stosu, używaj popUpTo(startDestination) { inclusive = true } przed navigate. Gwarantuje to, że stos nie zawiera więcej niż 5–7 ekranów jednocześnie.
Tak, kombinacja Push i Modal to standardowy wzorzec. Na przykład lista → Push do szczegółów → Modal do autoryzacji. Zaleca się nie umieszczać Push wewnątrz Modal: okno modalne nie powinno zawierać nawigacji stosowej. Jeśli wewnątrz okna modalnego potrzebna jest sekwencja ekranów — użyj Push wewnątrz kontenera modalnego.
Deep Links w nawigacji Push otwierają aplikację na konkretnym ekranie. iOS używa schematów URL i Universal Links z UINavigationController. Android używa Intent Filters z NavDeepLink. W obu przypadkach system analizuje link i tworzy stos nawigacyjny do docelowego ekranu, zachowując możliwość powrotu.
iOS używa standardowej animacji slajdu, którą można dostosować przez UINavigationControllerDelegate. Android Navigation Component obsługuje niestandardowe animacje przez zasoby XML (slide_in_right, slide_out_left). Dla Compose używaj AnimatedNavHost z modyfikatorem animateItemPlacement.
Podsumowanie
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.
Przeczytaj również