Tùy chỉnh thanh điều hướng trong iOS

Tram Ho

Introduction

Như chúng ta đã biết, navigation bar là một thành phần quan trọng, không thể thiếu trong hầu hết các app hiện nay. Tuy nhiên, navigation bar mặc định của iOS đôi lúc không đáp ứng được nhu cầu thiết kế UI. Vì vậy, customize navigation bar là một công việc cơ bản mà bất kỳ iOS developer nào cũng nên biết.

Trong bài viết này, chúng ta sẽ cùng tìm hiểu về cấu trúc của navigation bar cũng như các cách customize đơn giản nhất.

The parts of a navigation bar

Navigation bar mặc định sẽ có giao diện như sau:

Một navigation bar đã được customize:

Một navigation bar cơ bản bao gồm các thành phần chính sau:

  1. Background
  2. Title
  3. Bar buttons
  4. Back button
  5. Shadow, separator

Background

Thay đổi background color của navigation bar chỉ cần đoạn code đơn giản sau:

Điều đáng chú ý ở đây là cần sử dụng đúng property barTintColor. Không như các UIView bình thường chỉ cần thay đổi property backgroundColor hay tintColor, với navigation bar, chúng ta nên sử dụng barTintColor.

Title

Cách đơn giản nhất để customize appearance của title và status bar đó là thay đổi bar style:

Value .default của property này sẽ cho phép hiển thị navigation bar có background trắng và content (title và status bar) màu đen. Ngược lại, nếu đổi style sang kiểu .black thì title và status bar sẽ chuyển thành màu trắng.

Để có thể customize navigation bar title sâu hơn, chúng ta có thể sử dụng property text attributes của nó như sau:

Sử dụng text attributes, chúng ta không những có thể thay đổi màu text hay font chữ mà còn có thể customize baseline offset, spelling, shadow và nhiều setting khác.

Nếu không muốn hiển thị title trên navigation bar, chúng ta có thể tạo các ra view bình thường, customize tùy ý rồi set titleView bằng view vừa tạo.

Bar buttons

UIBarButtonItem có thể được khởi tạo theo nhiều cách.

Tùy theo vào giá trị của property style.plain hay .done mà font chữ sẽ regular hay bold.

Để thay đổi màu của bar button, chúng ta nên sử dụng property .tintColor của navigation bar:

Ngoài ra, để customize bar button, chúng ta vẫn có thể dùng text attibutes tương như như với navigation bar title:

Cần chú ý rằng các bar button là property của navigation item của view controller, chứ không phải của navigation bar.

Button with default system design

iOS cũng cung cấp các bar button hệ thống với các design có sẵn. Ví dụ, để tạo một right bar button item hình camera:

Điều này đôi khi rất hữu dụng. Đầu tiên, khi sử dụng các system bar button item này, chúng ta sẽ không cần quan tâm đến design, image… của các action cơ bản như “cancel”, “save” hay “edit”. Vì iOS sẽ tự động hiển thị các button theo theme, style mặc định của hệ thống, rất thân thiện và dễ hiểu với user. Khi các version iOS mới được cập nhật, theme style thay đổi, các button này cũng sẽ được apply phong cách mới một cách tự động.

Icon button

Nếu muốn thay đổi icon image của bar button item, có thể sử dụng cách sau:

Màu của icon sẽ do property .tintColor của navigation bar quyết định. Image size cho các kiểu màn hình có thể xem tại đây.

Button with a custom view

Nếu bạn vẫn muốn customize sâu hơn bar button item, chúng ta có thể khởi tạo bar button item với một customView tùy ý. Ví dụ:

Với các bar button được khởi tạo bằng custom view là UIButton thì sẽ không chịu ảnh hưởng từ property .tintColor. Vì vậy chúng ta có thể customize UI cho các state khác nhau (.normal, .highlighted) của bar button item như một button bình thường.

Back button

Back button thực chất vẫn là một bar button item, nhưng có thêm một số tính năng đặc biệt như:

  • Mặc định, bar button item này sẽ luôn có cả icon image và cả title label.
  • Có một property riêng trong navigationItem.backBarButtonItem.
  • Khi nhấn vào button này thì navigation controller sẽ popViewController(animated:), quay trở lại view controller trước đó.
  • Combine với một back swipe gesture của navigation controller. Cho phép swipe từ mép trái màn hình để pop view controller một cách từ từ.

Khi push một view controller mới vào stack của navigation controller thì back button này sẽ được iOS tự động thêm vào. Title mặc định của back button sẽ là title của view controller trước nó trong navigation controller

Nếu như view controller trước đó không có title, back button đơn giản sẽ không có title label. Trong trường hợp title của view controller mới được push và title của view controller trước quá dài, không thể đủ chỗ để hiển thị cả hai thì hệ thống sẽ ưu tiên hiển thị title của view controller hiện tại và thay title label của back button thành “Back” localized.

Để customize back button, ví dụ, thay đổi title label mặc định, chỉ cần khởi tạo một bar button item mới vào set lại vào property .backBarButtonItem của navigation item.

Nếu muốn ẩn back button title, chỉ cần set title bằng string rỗng:

Ngoài ra, khi customize back button, chúng ta còn có thể thêm code xử lý tùy ý khi thực hiện pop view controller.

Còn khi cần thay đổi cả image icon back mặc định, chúng ta hãy tạo một UIBarButtonItem mới không dùng text mà dùng ảnh:

Tuy nhiên, khi chạy app lên, chúng ta có thể thấy custom back button có ảnh vừa set và back button mặc định của iOS đè lên nhau.

Vì vậy, thay vì set bar button item vừa tạo thành back button, hãy set thành .leftBarButtonItem của navigation item.

Build và run app, mọi thứ trông đều rất ổn. Ngoại trừ một việc, đó là swipe gesture từ mép màn hình bên trái sẽ không còn hoạt động nữa.

Để enable lại swipe gesture này, chúng ta chỉ cần set delegate sau và conform view controller hiện tại với protocol UIGestureRecognizerDelegate mà không cần implement thêm bất kỳ delegate method nào.

Shadow/Separator

Shadow của navigation bar, hay còn có thể gọi là thanh separator ngăn cách giữ navigation bar và view bên dưới. Tuy nhiên, trong một số design UI, chúng ta cần phải ẩn thanh separator này.

Class UINavigationBar có một property tên là shadowImage. Document trên trang chủ Apple mô tả như sau:

The default value is nil, which corresponds to the default shadow image. When non-nil, this property represents a custom shadow image to show instead of the default.

Giá trị mặc định của shadowImage là nil, khi này navigation sẽ hiển thị thanh separator mặc định như chúng ta thường thấy.

Để thay đổi shadow image, hãy tạo một mono color image bằng code:

Ngoài ra, để xóa separator giữa navigation bar và view. Đơn giản, chỉ cần set:

Từ iOS 11 trở về trước ngoài việc phải set shadow image như trên, chúng ta còn phải set background image cho cả navigation bar:

Từ sau iOS 11 thì không cần set background image nữa, chỉ cần set shadow image là đủ.

Incapsulating the customisation

Code customize navigation bar có thể tổng hợp và viết sau khi khởi tạo navigation controller. Ví dụ:

Cách làm này chỉ áp dụng cho navigation bar của một instance navigation controller chứ không áp dụng cho tất cả. Nếu muốn tái sử dụng code, chúng ta có thể tạo thành method utility như sau:

Sau khi khởi tạo mỗi navigation controller, chỉ cần gọi method trên và truyền navigation controller vừa tạo vào để apply các customization.

Một cách nữa đó là tạo một base class cho UINavigationController.

Hoặc có thể tạo method extension cho UINavigationController.

Source article:
https://dmtopolog.com/navigation-bar-customization/

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo