Các điểm chính
Dynamic Type là công nghệ của Apple cho phép phông chữ ứng dụng tự động chia tỷ lệ khi kích thước văn bản hệ thống thay đổi. Người dùng đặt kích thước ưa thích trong Cài đặt → Trợ năng → Hiển thị & Kích thước Văn bản và tất cả ứng dụng hỗ trợ Dynamic Type điều chỉnh cỡ chữ mà không cần khởi động lại.
Hệ thống cung cấp 11 cấp độ chia tỷ lệ: từ XS (14pt cơ bản) đến XXXL (23pt cơ bản), cùng với 5 kích thước trợ năng bổ sung (AX1–AX5) cho người dùng khiếm thị nghiêm trọng. Khi kích thước thay đổi, iOS tạo thông báo UIContentSizeCategory.didChangeNotification và ứng dụng phải tải lại phông chữ qua UIFontMetrics. Theo Apple Human Interface Guidelines, Dynamic Type không thay đổi khoảng cách dòng hoặc tỷ lệ chữ — chỉ kích thước phông chữ, giữ khả năng đọc ở mọi kích thước.
Dynamic Type bắt buộc đối với các ứng dụng nhắm đến trạng thái trợ năng. Tại WWDC 2024, Apple thông báo rằng các ứng dụng không hỗ trợ kiểu động có nguy cơ bị từ chối khi xét duyệt nếu chức năng chính liên quan đến đọc văn bản. Trong các dự án IT Sectr, chúng tôi triển khai Dynamic Type từ phiên bản đầu tiên — giúp tiết kiệm đến 20% thời gian cho việc điều chỉnh trợ năng sau này.
Apple cung cấp 11 kiểu văn bản được xác định trước, mỗi kiểu được hiển thị qua UIFontDescriptor.UIAttributes cho phông chữ hệ thống SF Pro. Nhà phát triển không chỉ định kích thước pixel — họ chọn kiểu ngữ nghĩa và iOS áp dụng kích thước phông chữ thực tế dựa trên cài đặt của người dùng.
| Kiểu | Kích thước (mặc định) | Kích thước (AX5) | Mục đích sử dụng |
|---|---|---|---|
| .largeTitle | 34pt | 62pt | Tiêu đề màn hình cấp một |
| .title1 | 28pt | 50pt | Tiêu đề phụ |
| .title2 | 22pt | 40pt | Tiêu đề phần |
| .title3 | 20pt | 36pt | Tiêu đề nhỏ |
| .headline | 17pt semibold | 31pt | Văn bản nổi bật trong danh sách |
| .body | 17pt | 31pt | Văn bản nội dung |
| .callout | 16pt | 29pt | Chú thích và văn bản bổ sung |
| .subheadline | 15pt | 27pt | Nhãn phần tử |
| .footnote | 13pt | 23pt | Chú thích cuối và văn bản nhỏ |
| .caption1 | 12pt | 21pt | Chú thích hình ảnh |
| .caption2 | 11pt | 19pt | Nhãn và chú thích nhỏ |
Mỗi kiểu sử dụng phông chữ hệ thống SF Pro với độ đậm cố định (Regular cho body, Bold cho headline). Phông chữ tùy chỉnh được kết nối qua UIFontMetrics — cách duy nhất để điều chỉnh phông chữ bên thứ ba theo kiểu động.
UIFontMetrics là một lớp được giới thiệu trong iOS 11, giúp chia tỷ lệ bất kỳ UIFont nào theo tỷ lệ với kiểu văn bản đã chọn. Trước iOS 11, các nhà phát triển sử dụng lệnh gọi trực tiếp đến preferredFontForTextStyle, chỉ trả về phông chữ hệ thống SF Pro. UIFontMetrics giải quyết vấn đề này: nó nhận bất kỳ phông chữ nào và trả về phiên bản đã chia tỷ lệ, giữ nguyên độ đậm và tỷ lệ.
Phương thức scaledFont(for:) tính toán hệ số chia tỷ lệ dựa trên kích thước văn bản hiện tại của người dùng: nếu Lớn được chọn, hệ số là 1.0; nếu Rất lớn (AX1) — khoảng 1.3; cho Tối đa (AX5) — lên đến 1.8. Hệ số được áp dụng cho kích thước cơ sở của phông chữ tùy chỉnh, không phải hệ thống — điều này đảm bảo ý đồ của nhà thiết kế được giữ nguyên ở mọi kích thước.
UIFontMetrics được khuyến nghị cho tất cả phông chữ tùy chỉnh trong ứng dụng. Tại WWDC 2024, Apple đã giới thiệu công cụ Accessibility Inspector, kiểm tra hỗ trợ Dynamic Type và làm nổi bật các phần tử sử dụng kích thước phông chữ cố định thay vì UIFontMetrics. Tại IT Sectr, chúng tôi đã triển khai UIFontMetrics trong tất cả dự án từ năm 2018 — giúp giảm 35% lỗi chồng chéo văn bản.
Cách đơn giản nhất để có phông chữ động cho một nhãn. Mã cho thấy cách đặt UILabel với kiểu .body tự động phản hồi các thay đổi kích thước văn bản hệ thống.
import UIKit
class GreetingViewController: UIViewController {
private let label: UILabel = {
let l = UILabel()
l.text = "Hello, Dynamic Type!"
l.font = UIFont.preferredFont(forTextStyle: .body)
l.adjustsFontForContentSizeCategory = true
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: view.centerXAnchor),
label.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
}
}
Cờ adjustsFontForContentSizeCategory = true tự động cập nhật phông chữ khi kích thước văn bản hệ thống thay đổi — không có cờ này, Dynamic Type sẽ không hoạt động cho nhãn hiện có. Khi kích thước thay đổi, iOS gọi layoutIfNeeded và nhãn cập nhật phông chữ mà không cần can thiệp thủ công.
Khi sử dụng phông chữ tùy chỉnh (ví dụ: Montserrat), gọi preferredFontForTextStyle sẽ trả về SF Pro, không phải phông chữ của bạn. UIFontMetrics chia tỷ lệ phông chữ tùy chỉnh một cách cụ thể, giữ nguyên thiết kế của nó.
import UIKit
extension UIFont {
static func customDynamicFont(name: String,
size: CGFloat,
style: UIFont.TextStyle) -> UIFont {
guard let baseFont = UIFont(name: name, size: size) else {
return .preferredFont(forTextStyle: style)
}
return UIFontMetrics(forTextStyle: style).scaledFont(for: baseFont)
}
}
let titleFont = UIFont.customDynamicFont(
name: "Montserrat-Bold",
size: 20,
style: .title3
)
Phương thức scaledFont(for:) nhận một UIFont cơ sở và trả về phiên bản đã chia tỷ lệ tương ứng với kiểu .title3. Ở kích thước trợ năng AX5, phông Montserrat-Bold 20pt trở thành ~36pt — chính xác bằng mức tăng của phông hệ thống của kiểu này. Tại IT Sectr, chúng tôi đã sử dụng mẫu này trong tất cả dự án có phông chữ tùy chỉnh từ năm 2018, giúp loại bỏ hoàn toàn các khiếu nại về chữ nhỏ từ người dùng khiếm thị.
Nếu bạn cập nhật phông chữ thủ công (không có adjustsFontForContentSizeCategory), hãy đăng ký thông báo UIContentSizeCategory.didChangeNotification. Điều này cần thiết cho các phần tử UI tùy chỉnh không kế thừa cập nhật phông chữ tự động.
import UIKit
class DynamicLabel: UILabel {
private var customFont: UIFont?
private var textStyle: UIFont.TextStyle = .body
func configure(font: UIFont, style: UIFont.TextStyle) {
customFont = font
textStyle = style
NotificationCenter.default.addObserver(
self,
selector: #selector(updateFont),
name: UIContentSizeCategory.didChangeNotification,
object: nil
)
updateFont()
}
@objc private func updateFont() {
guard let base = customFont else { return }
self.font = UIFontMetrics(forTextStyle: textStyle).scaledFont(for: base)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
Đăng ký didChangeNotification đảm bảo phần tử tùy chỉnh cập nhật phông chữ mỗi khi cài đặt hệ thống thay đổi mà không cần khởi động lại ứng dụng. Kể từ iOS 15, thông báo đến ngay cả khi kích thước văn bản được thay đổi qua Trung tâm điều khiển trong các ứng dụng hỗ trợ Live Text Size.
Câu hỏi thường gặp
Dynamic Type khả dụng trên iOS 7 trở lên. UIFontMetrics xuất hiện trong iOS 11 — trước đó phương thức preferredFontForTextStyle được sử dụng trực tiếp. Trên iOS 15+, kiểu động hỗ trợ thêm kích thước trợ năng (AX1–AX5) cho phông chữ lớn. Các ứng dụng hỗ trợ iOS 10 trở xuống sử dụng preferredFontForTextStyle mà không có UIFontMetrics, giới hạn hỗ trợ chỉ với phông hệ thống SF Pro.
Trong Xcode 15+, mở trình mô phỏng và chọn Cài đặt → Trợ năng → Hiển thị & Kích thước Văn bản → Văn bản lớn hơn. Kéo thanh trượt để thay đổi kích thước. Trong Xcode, có Debug → Accessibility Inspector, làm nổi bật các phần tử có phông chữ cố định. Để tự động hóa, hãy sử dụng bài kiểm tra thay đổi UISlider cài đặt qua XCUITest — điều này đảm bảo tất cả màn hình được xây dựng lại chính xác.
Có, Auto Layout với kiểu động yêu cầu sử dụng intrinsicContentSize trên UILabel và UIButton. Ở kích thước trợ năng, văn bản có thể vượt quá ranh giới superview — thêm UIScrollView hoặc tăng ràng buộc leading/trailing. Sử dụng UIFontMetrics.scaledValue cho khoảng đệm, để khoảng cách chữ cũng được chia tỷ lệ tương ứng với phông chữ.
Tổng kế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