Push Presentation — паттерн навигации в мобильных приложениях, при котором каждый новый экран добавляется в стек навигации поверх предыдущего. Пользователь может последовательно переходить вперёд по контенту и возвращаться назад через системную кнопку или свайп. По данным Apple Developer, 2025, UINavigationController используется в 85% iOS-приложений как основной навигационный паттерн. В Android аналогичная функциональность реализуется через FragmentManager и NavController из Navigation Component.
Главное
Push Presentation — это механизм навигации, при котором каждый новый экран помещается на вершину стека, а предыдущий экран остаётся в памяти под ним. Пользователь продвигается вглубь контента, последовательно открывая детальные экраны, а кнопка назад возвращает его на предыдущий шаг.
Архитектура Push-навигации основана на структуре данных LIFO (Last In, First Out). Новый экран всегда добавляется в конец стека, а удаление происходит только с вершины. Это гарантирует предсказуемое поведение: пользователь всегда знает, что кнопка назад вернёт его ровно на один шаг назад. Стек навигации может содержать от 2 до 10+ экранов в зависимости от сложности приложения.
Push Presentation — основной паттерн в приложениях с иерархическим контентом: новостные ленты, каталоги товаров, многоуровневые меню и документация. По данным Material Design, стековая навигация подходит для сценариев, где пользователь исследует контент от общего к частному, а каждый следующий экран углубляет понимание темы.
Навигационный стек — это упорядоченный набор экранов, где каждый элемент хранит состояние своего ViewController или Fragment. При Push-операции новый экран добавляется в стек, его отображение анимируется (слайд справа в iOS, слайд снизу или Fade в Android), и он становится активным.
При Pop-операции (нажатие назад) верхний экран удаляется из стека, уничтожается или уходит в память, а предыдущий экран становится активным. iOS по умолчанию уничтожает popped ViewController, освобождая память. Android может сохранять Fragment в back stack с возможностью восстановления без пересоздания.
Глубина стека влияет на производительность: каждый экран в стеке потребляет память. Рекомендуется не хранить более 10 экранов в стеке. Для глубокой навигации используйте PopToRoot или перезапуск стека с новым root-экраном. Navigation Component в Android автоматически управляет состоянием стека через SavedStateHandle.
UINavigationController — контейнерный контроллер iOS, управляющий стеком UIViewController. Он автоматически отображает навигационную панель (navigation bar) с заголовком текущего экрана и кнопкой возврата. Push-анимация по умолчанию — слайд справа налево, создающая у пользователя ощущение погружения в контент.
Добавление экрана выполняется через pushViewController(_:animated:). Удаление — через popViewController(animated:). Для возврата на root-экран используется popToRootViewController(animated:). UINavigationController также поддерживает программное управление стеком через свойство viewControllers — массив всех контроллеров в стеке.
Navigation bar содержит заголовок экрана (title), кнопку назад и опциональные кнопки действий. Начиная с iOS 11, Large Titles (prefersLargeTitles) позволяют отображать заголовок увеличенным шрифтом, который анимированно сжимается при скролле. Это улучшает навигационную иерархию и информирует пользователя о текущем разделе.
let detailVC = DetailViewController()
detailVC.title = "Item Details"
navigationController?.pushViewController(detailVC, animated: true)
// Pop to previous screen
navigationController?.popViewController(animated: true)
// Pop to root
navigationController?.popToRootViewController(animated: true)
Navigation Component — библиотека Android Jetpack для декларативной навигации. Она предоставляет NavController, управляющий фрагментами или compose-экранами через граф навигации (nav_graph). Push в Android аналогичен iOS: каждый новый Fragment добавляется в back stack, а кнопка назад возвращает предыдущий.
NavHost — контейнер, отображающий текущий пункт назначения из NavGraph. NavGraph — XML-файл, описывающий все экраны приложения и связи между ними. Переходы определяются через actions с указанием destination и опциональных аргументов. Navigation Component автоматически обрабатывает system back, анимации и сохранение состояния.
Для передачи данных между экранами Navigation Component поддерживает Safe Args — кодогенерацию type-safe классов-аргументов. Вместо ручного помещения данных в Bundle, разработчик объявляет аргументы в NavGraph и получает их через generated Directions и Args классы. Safe Args устраняет ошибки несоответствия типов и упрощает рефакторинг.
// NavGraph definition in 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) }
}
}
// Navigate programmatically
navController.navigate("detail/42")
Сочетание Bottom Navigation и Push-навигации — частый паттерн в мобильных приложениях. Каждая вкладка Bottom Navigation имеет собственный стек экранов. Navigation Component поддерживает это через NavHost per tab или единый NavHost с отдельными графами для каждой вкладки. Переключение вкладок не сбрасывает состояние push-стеков.
Push Presentation и Modal Presentation решают разные задачи навигации. Push предназначен для последовательного просмотра контента, где каждый новый экран углубляет контекст. Modal — для фокусных задач, требующих завершения. На практике важно выбирать правильный паттерн под конкретный сценарий.
Основные критерии выбора: если пользователь должен свободно возвращаться назад без потери контекста — выбирайте Push. Если задача временная и блокирует основной контент (форма, авторизация) — используйте Modal. Смешивание паттернов на одном экране (Push внутри Modal) допустимо, но требует чёткой визуальной иерархии.
Ошибкой является использование Modal для последовательностей экранов, которые логически являются частью основного потока. Например, мастер создания заказа (Step 1 → Step 2 → Step 3) лучше реализовать через Push внутри модального контейнера, а не через цепочку модальных окон. Это сохраняет навигационную иерархию и предсказуемость возврата.
Рассмотрим полную реализацию Push-навигации на обеих платформах. Swift пример демонстрирует UINavigationController с программным управлением стеком и обработкой глубоких ссылок. Kotlin пример показывает Navigation Component с NavHost, аргументами и анимациями.
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() })
}
}
}
Примеры показывают базовую Push-навигацию: список → детали. iOS использует сториборды и UINavigationController с ручной передачей данных. Android использует NavHost с type-safe аргументами и автоматическим управлением back stack. Оба подхода поддерживают глубокие ссылки, кастомные анимации и сохранение состояния при повороте.
Часто задаваемые вопросы
Push добавляет экран в стек UINavigationController с кнопкой возврата. Present открывает модальное окно без кнопки назад — пользователь должен явно закрыть его. Push подходит для последовательного контента, Present — для фокусных задач. В SwiftUI Push соответствует NavigationLink, а Present — .sheet.
Navigation Component предоставляет методы popBackStack до определённого пункта и popUpTo для очистки стека. Для предотвращения переполнения стека используйте popUpTo(startDestination) { inclusive = true } перед navigate. Это гарантирует, что стек не содержит более 5–7 экранов одновременно.
Да, комбинация Push и Modal — стандартный паттерн. Например, список → Push на детали → Modal для авторизации. Рекомендуется не вкладывать Push внутрь Modal: модальное окно не должно содержать стековой навигации. Если внутри модального окна нужна последовательность экранов — используйте Push внутри модального контейнера.
Deep Links в Push-навигации открывают приложение на конкретном экране. iOS использует URL-схемы и Universal Links с UINavigationController. Android использует Intent Filters с NavDeepLink. В обоих случаях система разбирает ссылку и создаёт навигационный стек до целевого экрана, сохраняя возможность вернуться назад.
iOS использует стандартную анимацию слайда, которая настраивается через UINavigationControllerDelegate. Android Navigation Component поддерживает кастомные анимации через XML-ресурсы (slide_in_right, slide_out_left). Для Compose используйте AnimatedNavHost с модификатором animateItemPlacement.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также