Skip to content
  • Home
  • Code
  • iOS & Swift
  • Combine
  • RxSwift
  • SwiftUI
  • Flutter & Dart
  • Tutorials
  • Art
  • Blog
Fx Studio
  • Home
  • Code
  • iOS & Swift
  • Combine
  • RxSwift
  • SwiftUI
  • Flutter & Dart
  • Tutorials
  • Art
  • Blog
Written by chuotfx on November 11, 2019

Basic iOS tutorial : Navigation Controller

iOS & Swift

Contents

  • Chuẩn bị
  • 1. UINavigationController
  • 2. Cấu trúc
    • Giải thích chút
  • 3. Điều hướng
    • 3.1. Khởi tạo
    • 3.2. Push
    • 3.3. Pop
    • 3.4. Pop to View Controller
    • 3.5. Pop to root
  • 4. Custom Navigation Bar
    • 4.1. Bar Item
      • Back Button
      • Left Items & Left Items
      • Right Item & Right Items
      • Item with icon & image
    • 4.2. Color
    • 4.3. Image
    • 4.4. appearance()
  • Tạm kết

Chào bạn đến với bài viết thuộc seri Lập trình iOS cho mọi người. Bài viết này sẽ nói về Navigation Controller và cách điều hướng các màn hình trong ứng dụng iOS.

Để vào bài thì bạn cần xem lại các chủ đề sau:

    • Bắt đầu iOS Project không sử dụng Storyboard với Xcode 11 và Swift 5.1
    • Basic iOS tutorial : ViewController life cycle
    • Protocol trong 10 phút
    • Basic iOS tutorial : Delegation Pattern

Kiến thức sẽ móc nối nhiều phần trước kia lại với nhau. Còn nếu bạn là fan cứng của Fx Studio và đã theo dõi hết các bài viết trước thì chúng ta …

Bắt đầu thôi!

Chuẩn bị

  • MacOS 10.14.4
  • Xcode 11.0
  • Swift 5.1

1. UINavigationController

Đặc trưng của các ứng dụng trên PC thì chúng hầu hết có 1 window và tất cả view hiển thị đều ở đó. Nhưng đối với mobile nói chung thì giới hạn về kích thước màn hình vẫn là điều lớn nhất. Nên giao diện phải được chia ra thành nhiều màn hình. Chúng sẽ được bố trí ở nhiều View Controller khác nhau. Vấn đề đặt ra là

Làm sao để di chuyển giữa các màn hình với nhau và luồng dữ liệu & sự kiện sẽ như thế nào?

Bài này sẽ chỉ giải quyết một phần của vấn đề trên vì việc di chuyển giữa các màn hình khác nhau thì phức tạp hơn nhiều. Nó còn được gọi là điều hướng ứng dụng. Bạn phải nắm rõ cấu trúc các màn hình trong ứng dụng của bạn thì mới điều khiển được chúng nó.

Quay vào trọng tâm của bài viết là Navigation Controller. Vậy nó là gì?

UINavigationController hay Navigation Controller là một container quản lý các View Controller con và điều hướng chúng. Trong đó, mỗi lần chỉ hiển thị được một View Controller con mà nó quản lý.

Ví dụ đơn giản về Navigation Controller

Navigation Controller giống như một ngăn xếp. View Controller được bỏ vào sau sẽ được hiển thị. Khi lấy ra một View Controller từ ngăn xếp thì View Controller được thêm vào trước đó sẽ được hiển thị. Tới khi nào tới View Controller đầu tiên thì không thể lấy ra được nữa.

Navigation được sử dụng vào việc điều hướng đơn giản khi muốn di chuyển qua các màn hình và quay lại. Các màn hình thường liên quan với nhau.

Vì UINavigationController cũng là con cháu của UIViewController. Nên đối tượng thể hiện của nó, có thể xét ở root của Window để điều hướng toàn bộ giao diện ứng dụng theo Navigation.

2. Cấu trúc

Cấu trúc của UINavigationController

Về mặt cấu trúc của Navigation Controller thì chúng ta có như sau:

  • viewControllers là một stack (array UIViewController) chứa các View Controller.
  • navigationBar hiển thị ở trên màn hình. Chứa thông tin của View Controller và các buttons
  • toolbar là phần hiển thị ở dưới màn hình. Chứa các items phục vụ các chứng năng khác nhau

Giải thích chút

Navigation Bar mặc định được hiển thị và được quản lý bởi Navigation Controller của chính nó. Navigation Controller cập nhật giao diện của navigation bar bằng cách sử dụng nội dung được cung cấp bởi thuộc tính viewControllers quy định stack của navigation.

  • View controllers:
    • Là stack của các viewControllers, là một mảng các view controllers.
    • View controller đầu tiên trong mảng là root view controller.
    • View controller cuối cùng trong mảng là view controller đang được hiển thị.
    • Sử dụng back button trên navigation bar để remove view controller trên cùng
  • Navigation bar:
    • Chia làm 3 phần: left item, middle item, right item
    • Left:
      • backBarButtonItem
      • leftBarButtonItem
      • leftBarButtonItems
    • Middle:
      • title
      • titleView
    • Right:
      • rightBarButtonItem
      • rightBarButtonItems

 

  • Navigation controller content view
    • Navigation Controller là một container, nó gắn nội dung của những view controller khác vào trong nó và quản lý thông qua thuộc tính view.
    • Khi xây dựng giao diện điều hướng, mỗi một view controller được push vào phải luôn có một đối tượng UINavigationItem.
    • Navigation item có nhiệm vụ thể hiện những thông tin của view controller chứa nó, bao gồm những button cũng như view được hiển thị trên navigation bar.
    • Để thay đổi nội dung của navigation bar, cần config các thuộc tính con của thuộc tính navigationItems của view controller nằm trong stack.
    • Để ẩn/hiện navigation bar, sử dụng thuộc tính isNavigationBarHidden hoặc setNavigationBarHidden(_:animated:)

3. Điều hướng

Chúng ta sẽ dùng iOS Project không sử dụng StoryBoard để thực hiện demo cho bài này.

3.1. Khởi tạo

Tạo 1 View Controller, đặt tên là FirstViewController

import UIKit

class FirstViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        title = "First VC"
    }
}

Chú ý:

  • title khi xét giá trị cho nó thì cũng chính là title của NavigationItem (middle)

Mở file SceneDelegate.swift tiền hành edit đoạn code sau:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = (scene as? UIWindowScene) else { return }
        let window = UIWindow(windowScene: windowScene)
        
        let vc = FirstViewController()
        let navi = UINavigationController(rootViewController: vc)
        
        window.rootViewController = navi
        
        self.window = window
        window.makeKeyAndVisible()
    }

Việc tạo 1 đối tượng UINavigationController thì cần có 1 rootViewController. Đó chính là đối tượng vc khởi tạo từ class FirstViewController. Quá đơn giản, EZ

3.2. Push

Để đưa một màn hình khác vào thì sử dụng hàm push của Navigation Controller. Chúng ta tiếp tục với file FirstViewController.swift

  • Thêm 1 UIButton & 1 IBAction cho nó
@IBAction func push(_ sender: Any) {
        let vc = SecondViewController()
        self.navigationController?.pushViewController(vc, animated: true)
    }

Tại mỗi UIViewController thì có biến navigationController. Biến này sẽ trỏ tới đối tượng navigationController được tạo ra và gán cho root của Window.

Có thêm tham số animated để cho có hiệu ứng khi đưa 1 View Controller khác vào.

Chú ý: đối tượng View Controller trước đó vẫn còn tồn tại. Nó chỉ bị View Controller (push vào) đè lên mà thôi. 2 function viewWillDisappear & viewDidDisappear sẽ được gọi.

Xem full code cho FirstViewController

import UIKit

class FirstViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        title = "First VC"
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        print("view Will Disappear")
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        print("view Did Disappear")
    }
    
    
    @IBAction func push(_ sender: Any) {
        let vc = SecondViewController()
        self.navigationController?.pushViewController(vc, animated: true)
    }
    
}

Kết quả sau khi nhấn button.

3.3. Pop

Để lấy 1 View Controller ra khỏi Navigation Controller thì sử dụng hàm pop. Mở file SecondViewController và tiến hành code.

  • Tạo 1 UIButton và 1 IBAction cho nó
@IBAction func pop(_ sender: Any) {
        self.navigationController?.popViewController(animated: true)
    }

Rất là đơn giản:

  • animated để cho có hiệu ứng khi lấy ra hay không

Chú ý: khi thực hiện lệnh này thì View Controller được push vào sau cùng sẽ được lấy ra đầu tiên. Đối tượng View Controller đó sẽ bị giải phỏng. Nên vấn đề đảm bảo việc truyền dữ liệu sẽ rất quan trọng.

3.4. Pop to View Controller

Khi quá nhiều View Controller được push vào Navigation Controller và muốn pop ra một lúc nhiều màn hình thì chúng ta sử dụng hàm popToViewController(:)

Mở file ThirdViewController

  • Thêm 1 UIButton và 1 IBAction
    @IBAction func popController(_ sender: Any) {
        let vc = (self.navigationController?.viewControllers[1])!
        self.navigationController?.popToViewController(vc, animated: true)
        
    }

Để pop tới đối tượng View Controller thì cần phải xác định chính xác nó đang ở đâu trong stack hay navigationController?.viewControllers . Khi lấy được nó, thì nó sẽ là đối số của hàm.

Lưu ý:

  • Tránh việc muốn về SecondViewController mà new một đối tượng đó ra và truyền vào hàm. Kết quả là crash chương trình
  • Vì đối tượng cần pop ra thì phải đang tồn tại trong stack của Navigation Controller

Chú ý: khi pop tới đối tượng View Controller nào, thì đối tượng đó và các đối tượng sau nó (được push vào sau nó) sẽ được giải phóng hết. Các đối tượng View Controller trước đó sẽ vẫn còn tồn tại.

3.5. Pop to root

Khi bạn quá mệt mỏi với việc pop từng View Controller hay nhiều View Controller. Và đôi lúc chúng ta cũng không xác định là có bao nhiêu đối tượng View Controller để pop mà muốn về View Controller đầu tiên thì sử dụng hàm popToRootViewController.

Tham khảo code sau:

@IBAction func popRoot(_ sender: Any) {
        self.navigationController?.popToRootViewController(animated: true)
    }

Với lệnh này, thì toàn bộ các View Controller được push vào Navigation Controller sẽ được lấy ra hết. Chỉ riêng rootViewController lúc khởi tạo Navigation Controller sẽ được giữ lại.

Chú ý: tất cả các đối tượng View Controller sẽ bị giải phóng, trừ rootViewController của Navigation Controller.

4. Custom Navigation Bar

Chúng ta sẽ làm một số custom đơn giản đối với Navigation Bar. Đầu tiên xem qua cấu trúc của Navigation Bar như thế nào?

4.1. Bar Item

Back Button

Đôi khi bạn khó chịu khi title của View Controller trước đó cứ hiện ở backBarButtonItem thì muốn custom nó cũng đơn giản thôi. Tham khảo code sau

let backButton = UIBarButtonItem(title: "Back", style: .plain, target: self, action: nil)
navigationItem.backBarButtonItem = backButton

Kết quả

Chú ý: khi bạn thêm back button  ở đối tượng View Controller nào thì nó sẽ ảnh hưởng ở các màn hình sau. Chứ nó không ảnh hưởng tới màn hình đang hiển thị là chinh View Controller đó.

Left Items & Left Items

Thêm 1 button vào phía trái của Navigation Bar Item

let leftButton = UIBarButtonItem(title: "Left", style: .plain, target: self, action: #selector(leftAction))
navigationItem.leftBarButtonItem = leftButton

Chú ý về function của tham số action thì cần phải có từ khoá @objc

@objc func leftAction() {
        print("taped")
    }

Thêm nhiều button vào phía trái

let leftButton1 = UIBarButtonItem(title: "Left 1", style: .plain, target: self, action: #selector(leftAction))
let leftButton2 = UIBarButtonItem(title: "Left 2", style: .plain, target: self, action: #selector(leftAction))
        
navigationItem.leftBarButtonItems = [leftButton1, leftButton2]

Chú ý leftBarButtonItems có thêm 1 chữ s và nó được gán bằng 1 array.

Right Item & Right Items

Tương tự như bên trái, chúng ta cũng tạo ra các Bar Button Item và thêm chúng vào.

  • rightBarButtonItem thêm 1 item

  • rightBarButtonItems thêm nhiều item

Kết quả

Item with icon & image

Thêm phần thú vị cho cuộc sống, thì chúng ta có thể các icon của hệ thống hay các ảnh cho các đối tượng Bar Button Item. Tham khảo đoạn code sau:

        let searchItem = UIBarButtonItem(barButtonSystemItem: .search, target: self, action: #selector(tap))
        let bookMarkItem = UIBarButtonItem(barButtonSystemItem: .bookmarks, target: self, action: #selector(tap))
        
        let settingItem = UIBarButtonItem(image: UIImage(named: "setting-icon"), style: .plain, target: self, action: #selector(tap))
        
        navigationItem.rightBarButtonItems = [searchItem, bookMarkItem, settingItem]

Kết quả:

4.2. Color

Chúng ta tham khảo các cách thay đổi màu sắc trên Navigation Controller với UINavigationBar của nó.

  • bar background
navi.navigationBar.backgroundColor = .cyan

  • tintColor
navi.navigationBar.tintColor = .systemPink

  • barTintColor
navi.navigationBar.barTintColor = .systemPink

  • title color
navi.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.red]

4.3. Image

Thay đổi ảnh cho background thông qua function setBackgroundImage

self.navigationController?.navigationBar .setBackgroundImage(UIImage(named: "cricket"), for: .default)

4.4. appearance()

Có một cách khác để bạn có thể custom Navigation Bar một lần cho toàn bộ app, cho toàn bộ UINavigationController. Đó là sử dụng appearance(). Cách sử dụng như sau:

let navigationBarAppearance = UINavigationBar.appearance()

navigationBarAppearance.barTintColor = .someUIColor
navigationBarAppearance.titleTextAttributes = myTextAttributes
navigationBarAppearance.largeTitleTextAttributes = myTextAttributes

 

Tới đây cũng khá nhiều rồi, tạm thời thì bạn đã đầy đủ vũ khí để điều hướng các màn hình trong ứng dụng của bạn với Navigation Controller. Chúc bạn thành công!

Tạm kết

  • Tìm hiểu về UINavigationController
  • Cấu trúc của Navigation Controller
  • Điều hướng trong ứng dụng iOS
  • Custom Navigation Bar
FacebookTweetPinYummlyLinkedInPrintEmailShares57

Related Posts:

  • feature_bg_3
    Clean Architecture trong iOS
  • testing
    Hello Testing iOS
Tags: basic ios tutorial, iOS, navigation
Written by chuotfx

Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Donate – Buy me a coffee!

Fan page

Fx Studio

Tags

Actor Advanced Swift AI api AppDistribution autolayout basic ios tutorial blog ci/cd closure collectionview combine concurrency crashlytics dart dart basic dart tour Declarative delegate deploy design pattern fabric fastlane firebase flavor flutter GCD gradients iOS MVVM optional Prompt engineering protocol Python rxswift safearea Swift Swift 5.5 SwiftData SwiftUI SwiftUI Notes tableview testing TravisCI unittest

Recent Posts

  • Vibe Coding là gì?
  • Cách Đọc Sách Lập Trình Nhanh và Hiệu Quả Bằng GEN AI
  • Nỗ Lực – Hành Trình Kiến Tạo Ý Nghĩa Cuộc Sống
  • Ai Sẽ Là Người Fix Bug Khi AI Thống Trị Lập Trình?
  • Thời Đại Của “Dev Tay To” Đã Qua Chưa?
  • Prompt Engineering – Con Đường Để Trở Thành Một Nghề Nghiệp
  • Vấn đề Ảo Giác (hallucination) khi tương tác với Gen AI và cách khắc phục nó qua Prompt
  • Điều Gì Xảy Ra Nếu… Những Người Dệt Mã Trở Thành Những Người Bảo Vệ Cuối Cùng Của Sự Sáng Tạo?
  • Khi Cô Đơn Gặp Python
  • Học vì tồn tại

You may also like:

  • Hello Testing iOS
    testing
  • Clean Architecture trong iOS
    feature_bg_3

Archives

  • April 2025 (1)
  • March 2025 (8)
  • January 2025 (7)
  • December 2024 (4)
  • September 2024 (1)
  • July 2024 (1)
  • June 2024 (1)
  • May 2024 (4)
  • April 2024 (2)
  • March 2024 (5)
  • January 2024 (4)
  • February 2023 (1)
  • January 2023 (2)
  • November 2022 (2)
  • October 2022 (1)
  • September 2022 (5)
  • August 2022 (6)
  • July 2022 (7)
  • June 2022 (8)
  • May 2022 (5)
  • April 2022 (1)
  • March 2022 (3)
  • February 2022 (5)
  • January 2022 (4)
  • December 2021 (6)
  • November 2021 (8)
  • October 2021 (8)
  • September 2021 (8)
  • August 2021 (8)
  • July 2021 (9)
  • June 2021 (8)
  • May 2021 (7)
  • April 2021 (11)
  • March 2021 (12)
  • February 2021 (3)
  • January 2021 (3)
  • December 2020 (3)
  • November 2020 (9)
  • October 2020 (7)
  • September 2020 (17)
  • August 2020 (1)
  • July 2020 (3)
  • June 2020 (1)
  • May 2020 (2)
  • April 2020 (3)
  • March 2020 (20)
  • February 2020 (5)
  • January 2020 (2)
  • December 2019 (12)
  • November 2019 (12)
  • October 2019 (19)
  • September 2019 (17)
  • August 2019 (10)

About me

Education, Mini Game, Digital Art & Life of coders
Contacts:
contacts@fxstudio.dev

Fx Studio

  • Home
  • About me
  • Contact us
  • Mail
  • Privacy Policy
  • Donate
  • Sitemap

Categories

  • Art (1)
  • Blog (43)
  • Code (10)
  • Combine (22)
  • Flutter & Dart (24)
  • iOS & Swift (101)
  • No Category (1)
  • RxSwift (37)
  • SwiftUI (80)
  • Tutorials (86)

Newsletter

Stay up to date with our latest news and posts.
Loading

    Copyright © 2025 Fx Studio - All rights reserved.