Push Presentation là một mẫu điều hướng trong ứng dụng di động, nơi mỗi màn hình mới được thêm vào ngăn xếp điều hướng phía trên màn hình trước đó. Người dùng có thể tiến tuần tự qua nội dung và quay lại bằng nút hệ thống hoặc thao tác vuốt. Theo Apple Developer, 2025, UINavigationController được sử dụng trong 85% ứng dụng iOS như mẫu điều hướng chính. Trên Android, chức năng tương tự được triển khai thông qua FragmentManager và NavController từ Navigation Component.
Những điểm chính
Push Presentation là một cơ chế điều hướng trong đó mỗi màn hình mới được đặt lên đỉnh của ngăn xếp, trong khi màn hình trước đó vẫn nằm trong bộ nhớ bên dưới. Người dùng đi sâu vào nội dung bằng cách mở tuần tự các màn hình chi tiết và nút quay lại đưa họ trở về bước trước.
Kiến trúc của điều hướng Push dựa trên cấu trúc dữ liệu LIFO (Last In, First Out). Một màn hình mới luôn được thêm vào cuối ngăn xếp và việc xóa chỉ xảy ra từ đỉnh. Điều này đảm bảo hành vi có thể dự đoán được: người dùng luôn biết rằng nút quay lại sẽ đưa họ về đúng một bước. Ngăn xếp điều hướng có thể chứa từ 2 đến 10+ màn hình tùy thuộc vào độ phức tạp của ứng dụng.
Push Presentation là mẫu chính trong các ứng dụng có nội dung phân cấp: nguồn cấp tin tức, danh mục sản phẩm, menu đa cấp và tài liệu. Theo Material Design, điều hướng ngăn xếp phù hợp cho các tình huống người dùng khám phá nội dung từ tổng quát đến cụ thể và mỗi màn hình tiếp theo đào sâu hiểu biết về chủ đề.
Ngăn xếp điều hướng là một tập hợp có thứ tự các màn hình, nơi mỗi phần tử lưu trữ trạng thái của ViewController hoặc Fragment của nó. Trong một thao tác Push, một màn hình mới được thêm vào ngăn xếp, sự xuất hiện của nó được tạo hiệu ứng (trượt từ phải trong iOS, trượt từ dưới hoặc Fade trong Android) và nó trở thành hoạt động.
Trong một thao tác Pop (nhấn quay lại), màn hình trên cùng bị xóa khỏi ngăn xếp, bị hủy hoặc chuyển vào bộ nhớ và màn hình trước đó trở thành hoạt động. iOS theo mặc định hủy ViewController đã pop, giải phóng bộ nhớ. Android có thể lưu Fragment trong ngăn xếp quay lại với khả năng khôi phục mà không cần tạo lại.
Độ sâu của ngăn xếp ảnh hưởng đến hiệu suất: mỗi màn hình trong ngăn xếp tiêu tốn bộ nhớ. Khuyến nghị không giữ quá 10 màn hình trong ngăn xếp. Đối với điều hướng sâu, hãy sử dụng PopToRoot hoặc khởi động lại ngăn xếp với màn hình gốc mới. Navigation Component trên Android tự động quản lý trạng thái ngăn xếp thông qua SavedStateHandle.
UINavigationController là một bộ điều khiển vùng chứa iOS quản lý một ngăn xếp các UIViewController. Nó tự động hiển thị thanh điều hướng với tiêu đề màn hình hiện tại và nút quay lại. Hiệu ứng push mặc định là trượt từ phải sang trái, tạo cảm giác đắm chìm trong nội dung cho người dùng.
Việc thêm màn hình được thực hiện qua pushViewController(_:animated:). Việc xóa được thực hiện qua popViewController(animated:). Để quay lại màn hình gốc, hãy sử dụng popToRootViewController(animated:). UINavigationController cũng hỗ trợ quản lý ngăn xếp theo chương trình thông qua thuộc tính viewControllers — một mảng tất cả các bộ điều khiển trong ngăn xếp.
Thanh điều hướng chứa tiêu đề màn hình, nút quay lại và các nút hành động tùy chọn. Bắt đầu từ iOS 11, Large Titles (prefersLargeTitles) cho phép hiển thị tiêu đề với phông chữ mở rộng, thu nhỏ có hiệu ứng khi cuộn. Điều này cải thiện phân cấp điều hướng và thông báo cho người dùng về phần hiện tại.
let detailVC = DetailViewController()
detailVC.title = "Item Details"
navigationController?.pushViewController(detailVC, animated: true)
// Quay lại màn hình trước
navigationController?.popViewController(animated: true)
// Quay lại gốc
navigationController?.popToRootViewController(animated: true)
Navigation Component là một thư viện Android Jetpack cho điều hướng khai báo. Nó cung cấp NavController, quản lý các fragment hoặc màn hình Compose thông qua đồ thị điều hướng (nav_graph). Push trên Android tương tự iOS: mỗi Fragment mới được thêm vào ngăn xếp quay lại và nút quay lại trở về màn hình trước.
NavHost là một vùng chứa hiển thị điểm đến hiện tại từ NavGraph. NavGraph là một tệp XML mô tả tất cả màn hình ứng dụng và kết nối giữa chúng. Các chuyển tiếp được xác định thông qua actions chỉ định điểm đến và các đối số tùy chọn. Navigation Component tự động xử lý nút quay lại hệ thống, hiệu ứng động và lưu trạng thái.
Để truyền dữ liệu giữa các màn hình, Navigation Component hỗ trợ Safe Args — tạo mã các lớp đối số an toàn về kiểu. Thay vì đặt dữ liệu thủ công vào Bundle, nhà phát triển khai báo đối số trong NavGraph và nhận chúng thông qua các lớp Directions và Args được tạo. Safe Args loại bỏ lỗi không khớp kiểu và đơn giản hóa việc tái cấu trúc.
// Định nghĩa NavGraph trong 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) }
}
}
// Điều hướng theo chương trình
navController.navigate("detail/42")
Kết hợp Bottom Navigation và điều hướng Push là một mẫu phổ biến trong ứng dụng di động. Mỗi tab Bottom Navigation có ngăn xếp màn hình riêng. Navigation Component hỗ trợ điều này thông qua NavHost mỗi tab hoặc một NavHost duy nhất với đồ thị riêng cho mỗi tab. Chuyển tab không đặt lại trạng thái của các ngăn xếp push.
Push Presentation và Modal Presentation giải quyết các tác vụ điều hướng khác nhau. Push được thiết kế để xem nội dung tuần tự, nơi mỗi màn hình mới đào sâu ngữ cảnh. Modal dành cho các tác vụ tập trung yêu cầu hoàn thành. Trong thực tế, điều quan trọng là chọn đúng mẫu cho kịch bản cụ thể.
Tiêu chí lựa chọn chính: nếu người dùng cần có thể quay lại tự do mà không mất ngữ cảnh — hãy chọn Push. Nếu tác vụ tạm thời và chặn nội dung chính (biểu mẫu, ủy quyền) — hãy sử dụng Modal. Pha trộn các mẫu trên cùng một màn hình (Push bên trong Modal) có thể chấp nhận được nhưng yêu cầu phân cấp trực quan rõ ràng.
Một lỗi phổ biến là sử dụng Modal cho các chuỗi màn hình mà về mặt logic là một phần của luồng chính. Ví dụ: trình hướng dẫn tạo đơn hàng (Bước 1 → Bước 2 → Bước 3) tốt hơn nên triển khai qua Push bên trong vùng chứa modal thay vì qua một chuỗi cửa sổ modal. Điều này bảo toàn phân cấp điều hướng và khả năng dự đoán khi quay lại.
Hãy xem xét một triển khai hoàn chỉnh của điều hướng Push trên cả hai nền tảng. Ví dụ Swift minh họa UINavigationController với quản lý ngăn xếp theo chương trình và xử lý liên kết sâu. Ví dụ Kotlin cho thấy Navigation Component với NavHost, đối số và hiệu ứng động.
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() })
}
}
}
Các ví dụ cho thấy điều hướng Push cơ bản: danh sách → chi tiết. iOS sử dụng storyboard và UINavigationController với truyền dữ liệu thủ công. Android sử dụng NavHost với đối số an toàn về kiểu và quản lý ngăn xếp quay lại tự động. Cả hai cách tiếp cận đều hỗ trợ liên kết sâu, hiệu ứng động tùy chỉnh và lưu trạng thái khi xoay.
Câu hỏi thường gặp
Push thêm màn hình vào ngăn xếp UINavigationController với nút quay lại. Present mở cửa sổ modal không có nút quay lại — người dùng phải đóng nó một cách rõ ràng. Push phù hợp cho nội dung tuần tự, Present cho các tác vụ tập trung. Trong SwiftUI, Push tương ứng với NavigationLink và Present tương ứng với .sheet.
Navigation Component cung cấp các phương thức popBackStack đến một điểm cụ thể và popUpTo để dọn sạch ngăn xếp. Để ngăn tràn ngăn xếp, hãy sử dụng popUpTo(startDestination) { inclusive = true } trước navigate. Điều này đảm bảo ngăn xếp không chứa quá 5–7 màn hình đồng thời.
Có, kết hợp Push và Modal là một mẫu tiêu chuẩn. Ví dụ: danh sách → Push đến chi tiết → Modal để ủy quyền. Khuyến nghị không lồng Push bên trong Modal: cửa sổ modal không nên chứa điều hướng ngăn xếp. Nếu cần một chuỗi màn hình bên trong cửa sổ modal, hãy sử dụng Push bên trong vùng chứa modal.
Liên kết sâu trong điều hướng Push mở ứng dụng trên một màn hình cụ thể. iOS sử dụng lược đồ URL và Universal Links với UINavigationController. Android sử dụng Intent Filters với NavDeepLink. Trong cả hai trường hợp, hệ thống phân tích liên kết và tạo một ngăn xếp điều hướng đến màn hình mục tiêu, bảo toàn khả năng quay lại.
iOS sử dụng hiệu ứng trượt tiêu chuẩn, có thể tùy chỉnh qua UINavigationControllerDelegate. Android Navigation Component hỗ trợ hiệu ứng tùy chỉnh thông qua tài nguyên XML (slide_in_right, slide_out_left). Đối với Compose, hãy sử dụng AnimatedNavHost với bổ từ animateItemPlacement.
Tóm tắt
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm