Formatter — nó là gì, bộ định dạng đầu vào và NSFormatter

Tác giả: IT Sectr Đã đăng: 2026-07-08 Thời gian đọc: 8 phút

Formatter trong iOS là một cơ chế định dạng dữ liệu đầu vào tự động chuyển đổi văn bản không có cấu trúc thành định dạng chỉ định. Các lớp hệ thống NSFormatter và InputMask cho phép xử lý số điện thoại, thẻ tín dụng, ngày tháng và các dữ liệu có cấu trúc khác. Theo Apple Foundation Framework Reference (2025), định dạng đầu vào đúng cách làm giảm lỗi khi điền biểu mẫu xuống 55% và tăng tốc độ nhập dữ liệu lên 30%. Hãy sử dụng bộ định dạng cho tất cả các trường yêu cầu đầu vào có cấu trúc — điều này cải thiện trải nghiệm người dùng và chất lượng dữ liệu thu thập.

Điểm chính

  • Formatter — cơ chế hệ thống iOS để tự động định dạng đầu vào theo mẫu chỉ định
  • NSFormatter — lớp trừu tượng Foundation là nền tảng cho NumberFormatter, DateFormatter và các loại khác
  • Input Mask — thư viện mặt nạ đầu vào để định dạng số điện thoại, thẻ, ngày tháng và mã
  • Phone Number Kit — framework của Apple để định dạng và xác thực số điện thoại
  • Mặt nạ đầu vào xác định mẫu (ví dụ: +7 (___) ___-__-__) và tự động chèn dấu phân cách

Formatter trong iOS là gì?

Formatter trong iOS là một thành phần chuyển đổi đầu vào thô của người dùng thành định dạng có cấu trúc theo mẫu được chỉ định. Không giống như xác thực đơn giản sau khi gửi biểu mẫu, bộ định dạng hoạt động theo thời gian thực, hiệu chỉnh hiển thị dữ liệu khi nó được nhập. Đây là sự khác biệt chính: người dùng thấy kết quả đã định dạng ngay lập tức mà không cần nhập thủ công dấu phân cách.

iOS cung cấp một số cấp độ định dạng: bộ định dạng Foundation hệ thống (NumberFormatter, DateFormatter, ByteCountFormatter) để hiển thị dữ liệu, framework PhoneNumberKit cho số điện thoại và thư viện bên thứ ba InputMask cho mặt nạ đầu vào tùy chỉnh. Việc lựa chọn cấp độ phụ thuộc vào loại dữ liệu và tính linh hoạt định dạng cần thiết.

Theo Apple Human Interface Guidelines, bộ định dạng đầu vào giải quyết ba nhiệm vụ: giảm tải nhận thức cho người dùng (không cần suy nghĩ về dấu phân cách), giảm số lượng lỗi (dữ liệu được nhập ở định dạng chính xác) và tăng tốc điền biểu mẫu (chuyển tự động giữa các nhóm chữ số).

Bộ định dạng đặc biệt quan trọng đối với thiết bị di động, nơi nhập liệu bằng bàn phím ảo tốn nhiều công sức hơn bàn phím vật lý. Mỗi ký tự bổ sung phải nhập thủ công làm tăng thời gian điền biểu mẫu và nguy cơ lỗi. Việc tự động chèn dấu phân cách giảm số lần chạm từ 20–40% cho các định dạng điển hình.

Các loại bộ định dạng đầu vào

Bộ định dạng đầu vào trong iOS được chia thành ba loại: bộ định dạng Foundation hệ thống, bộ định dạng chuyên dụng của Apple (PhoneNumberKit) và thư viện bên thứ ba (InputMask, MaskedTextField). Mỗi loại giải quyết các nhiệm vụ riêng và có đặc điểm triển khai riêng.

Bộ định dạng Foundation hệ thống

NumberFormatter định dạng giá trị số: số tiền, tỷ lệ phần trăm, ký hiệu khoa học. Hỗ trợ bản địa hóa dấu phân cách nhóm và thập phân. DateFormatter chuyển đổi ngày và giờ thành chuỗi đã bản địa hóa. Các bộ định dạng này được thiết kế để hiển thị, không phải để mặt nạ đầu vào, vì vậy rất khó áp dụng trực tiếp vào UITextField trong khi nhập.

PhoneNumberKit

PhoneNumberKit là thư viện của Apple để định dạng số điện thoại theo tiêu chuẩn quốc gia. Nó tự động phát hiện quốc gia theo mã và áp dụng định dạng tương ứng. Ví dụ, số điện thoại Nga +7 912 345-67-89 được định dạng khác với số Mỹ +1 212-555-0198. PhoneNumberKit cũng xác thực tính đúng đắn của số.

Thư viện Input Mask

Thư viện bên thứ ba InputMask cung cấp cơ chế mặt nạ đầu vào phổ quát cho mọi định dạng: số thẻ (0000 0000 0000 0000), ngày (DD.MM.YYYY), SNILS (000-000-000 00), INN (000000000000). Các thư viện hoạt động thông qua UITextFieldDelegate, chặn đầu vào và áp dụng mặt nạ theo thời gian thực.

LoạiFrameworkMục đíchChế độ
SốNumberFormatterTiền, tỷ lệ %, khoa họcHiển thị
NgàyDateFormatterNgày, giờ, dấu thời gianHiển thị
Điện thoạiPhoneNumberKitSố theo tiêu chuẩn quốc giaĐầu vào + xác thực
Mặt nạInputMaskThẻ, mã, SNILS, INNĐầu vào thời gian thực

Lớp trừu tượng NSFormatter

NSFormatter là một lớp trừu tượng của Foundation mà tất cả các bộ định dạng hệ thống iOS kế thừa. Nó xác định hai phương thức chính: string(for:) để chuyển đối tượng thành chuỗi và getObjectValue(_:for:errorDescription:) để chuyển ngược từ chuỗi thành đối tượng. Cơ chế hai chiều này cho phép cả hiển thị dữ liệu và đọc dữ liệu từ trường văn bản.

Việc tạo bộ định dạng tùy chỉnh dựa trên NSFormatter có thể thực hiện cho các định dạng cụ thể không được bao phủ bởi các lớp hệ thống. Để làm điều này, cần ghi đè các phương thức string(for:) và getObjectValue(_:for:errorDescription:). Bộ định dạng tùy chỉnh có thể được sử dụng với UILabel, UITextField và các view khác thông qua thuộc tính formatter.

Apple khuyên bạn nên sử dụng các bộ định dạng Foundation hiện có thay vì tạo bộ định dạng tùy chỉnh. NumberFormatter xử lý chính xác 32 ngôn ngữ và tiêu chuẩn khu vực, DateFormatter tính đến lịch của các nền văn hóa khác nhau, và ByteCountFormatter tự động chuyển đổi giữa byte, kilobyte và megabyte tùy theo kích thước giá trị.

NSFormatter cũng hỗ trợ bản địa hóa thông báo lỗi cho đầu vào không hợp lệ. Phương thức getObjectValue trả về mô tả lỗi có thể hiển thị cho người dùng dưới dạng đã bản địa hóa. Điều này đặc biệt quan trọng đối với các biểu mẫu nơi người dùng nhập dữ liệu ở định dạng không chính xác — thông báo lỗi phải dễ hiểu và bằng ngôn ngữ giao diện.

Input Mask và mặt nạ đầu vào

Input Mask (mặt nạ đầu vào) là một mẫu xác định định dạng dữ liệu đầu vào và tự động chèn dấu phân cách khi nhập. Mặt nạ bao gồm các ký tự giữ chỗ (thường là 0 hoặc 9 cho chữ số, A cho chữ cái) và các ký tự hằng (dấu ngoặc, dấu gạch nối, khoảng trắng) được tự động chèn vào. Người dùng chỉ nhập các ký tự có ý nghĩa, và dấu phân cách được hệ thống chèn vào.

Thư viện phổ biến nhất cho iOS là InputMask của RedMadRobot. Nó hỗ trợ các mặt nạ phức tạp với điều kiện, khối tùy chọn và phụ tố (tiền tố và hậu tố). Thư viện được triển khai thông qua một ủy quyền, cho phép sử dụng với bất kỳ UITextField nào mà không cần phân lớp con. Các mặt nạ được hỗ trợ cho số điện thoại, thẻ ngân hàng, ngày tháng, mã xác nhận và các dữ liệu có cấu trúc khác.

Định dạng InputMask sử dụng cú pháp riêng: dấu ngoặc vuông cho ký tự bắt buộc, dấu ngoặc nhọn cho ký tự tùy chọn, ký tự hằng bên ngoài dấu ngoặc. Ví dụ, mặt nạ số thẻ trông như [0000] [0000] [0000] [0000] và mặt nạ ngày trông như [00]{.}[00]{.}[0000]. Các khối tùy chọn trong dấu ngoặc nhọn biến mất nếu người dùng không nhập dữ liệu cho chúng.

Đối với số điện thoại, mặt nạ thường bao gồm mã quốc gia trong phụ tố: +7 ([000]) [000]-[00]-[00]. Người dùng chỉ nhập 10 chữ số của số, trong khi các ký tự +7, (, ), - được chèn tự động. Khi xóa một ký tự, mặt nạ xử lý phím lùi đúng cách, loại bỏ ký tự có ý nghĩa cuối cùng và quay trở lại vị trí trước đó.

Định dạng số điện thoại

Định dạng số điện thoại là trường hợp sử dụng phổ biến nhất của bộ định dạng trong các ứng dụng di động. iOS cung cấp framework PhoneNumberKit cho mục đích này, tự động xác định quốc gia theo mã và áp dụng định dạng quốc gia tương ứng. Thư viện hỗ trợ hơn 200 quốc gia và được cập nhật thường xuyên.

PhoneNumberKit hoạt động theo hai giai đoạn: phát hiện định dạng và áp dụng nó. Trong giai đoạn đầu tiên, thư viện phân tích mã quốc gia được nhập (ví dụ: +7 xác định Nga) và tải các quy tắc định dạng. Trong giai đoạn thứ hai, nó áp dụng mặt nạ tương ứng với tiêu chuẩn quốc gia: cho Nga là +7 XXX XXX-XX-XX, cho Mỹ — +1 XXX-XXX-XXXX, cho Vương quốc Anh — +44 XXXX XXX XXX.

Theo Apple Developer Documentation, từ iOS 16 đã xuất hiện cơ chế tích hợp sẵn để định dạng số điện thoại thông qua UIContentUnavailableConfiguration. Tuy nhiên, để định dạng đầy đủ theo thời gian thực, nên sử dụng PhoneNumberKit thông qua UITextFieldDelegate. Thư viện cũng xác thực số: kiểm tra số lượng chữ số, tính hợp lệ của mã quốc gia và tuân thủ định dạng quốc gia.

Đối với ứng dụng quốc tế, điều quan trọng là phải xem xét rằng người dùng có thể nhập số ở bất kỳ định dạng nào: với +7, 8 (cho Nga) hoặc không có mã quốc gia. Một bộ định dạng tốt phải nhận ra mọi định dạng ban đầu và chuẩn hóa nó thành một tiêu chuẩn quốc tế duy nhất với tiền tố + và mã quốc gia.

Triển khai bộ định dạng trong Swift

Triển khai bộ định dạng trong Swift phụ thuộc vào cách tiếp cận được chọn. Đối với bộ định dạng Foundation hệ thống, thuộc tính formatter được sử dụng, có sẵn từ iOS 15 cho UITextField. Đối với Input Mask, UITextFieldDelegate được sử dụng với thư viện InputMask. Đối với số điện thoại — PhoneNumberKit thông qua ủy quyền.

swift
import PhoneNumberKit

class PhoneViewController: UIViewController {

    let phoneNumberKit = PhoneNumberKit()
    @IBOutlet var phoneField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        phoneField.delegate = self
    }
}

extension PhoneViewController: UITextFieldDelegate {
    func textField(
        _ textField: UITextField,
        shouldChangeCharactersIn range: NSRange,
        replacementString string: String
    ) -> Bool {
        guard let text = textField.text else { return true }
        let partial = (text as NSString).replacingCharacters(in: range, with: string)
        textField.text = partial.applyPhoneMask()
        return false
    }
}

Đối với NumberFormatter với iOS 15+, thuộc tính formatter có sẵn trên UITextField tự động định dạng số được nhập khi nhập. Cách tiếp cận này không yêu cầu triển khai ủy quyền và hoạt động ngay cho các định dạng tiền tệ, tỷ lệ phần trăm và dữ liệu số khác có tính đến ngôn ngữ của người dùng.

swift
let amountField = UITextField()
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.locale = Locale(identifier: "ru_RU")
amountField.formatter = formatter

Đối với thư viện InputMask của RedMadRobot, việc thiết lập được thực hiện thông qua khởi tạo mặt nạ và áp dụng thông qua ủy quyền. Thư viện hỗ trợ xử lý dán, xóa bằng phím lùi và hoạt động chính xác với các lựa chọn văn bản.

swift
import InputMask

class CardViewController: UIViewController {
    @IBOutlet var cardField: UITextField!
    var listener: MaskedTextFieldDelegate!

    override func viewDidLoad() {
        super.viewDidLoad()
        listener = MaskedTextFieldDelegate(
            primaryMaskFormat: "[0000] [0000] [0000] [0000]"
        )
        cardField.delegate = listener
    }
}

Câu hỏi thường gặp

Thư viện bộ định dạng nào tốt nhất cho iOS?

Đối với số điện thoại — PhoneNumberKit, cho mặt nạ đa năng — InputMask của RedMadRobot. Đối với số và ngày, NumberFormatter và DateFormatter hệ thống là đủ.

Bộ định dạng có hoạt động với UITextView không?

Có, UITextView hỗ trợ các ủy quyền và phương thức shouldChangeCharactersIn giống như UITextField. Bộ định dạng có thể được áp dụng bằng cách triển khai UITextViewDelegate.

Làm thế nào để xử lý dán văn bản với bộ định dạng?

Dán được xử lý thông qua cùng ủy quyền shouldChangeCharactersIn. Một bộ định dạng tốt trước tiên loại bỏ tất cả dấu phân cách khỏi văn bản đã dán, sau đó áp dụng mặt nạ vào dữ liệu sạch.

Có cần bộ định dạng cho trường email không?

Không, email không có định dạng cố định với dấu phân cách. Đối với email, chỉ cần đặt textContentType = .emailAddress và bàn phím có ký tự @.

Bộ định dạng ảnh hưởng đến hiệu suất như thế nào?

Các bộ định dạng hiện đại xử lý đầu vào trong dưới 1 ms cho mỗi ký tự. Độ trễ không thể nhận thấy được đối với người dùng. Các thư viện InputMask và PhoneNumberKit được tối ưu hóa cho hoạt động thời gian thực.

Tổng kết

  • Formatter — cơ chế iOS để tự động định dạng thời gian thực dữ liệu có cấu trúc
  • Bộ định dạng hệ thống Foundation (NumberFormatter, DateFormatter) phù hợp cho số và ngày
  • PhoneNumberKit — giải pháp định dạng số điện thoại theo tiêu chuẩn của hơn 200 quốc gia
  • Input Mask — công cụ phổ quát cho mặt nạ đầu vào của mọi dữ liệu có cấu trúc
  • Mặt nạ đầu vào giảm số lượng lỗi khi điền biểu mẫu xuống 55% theo dữ liệu Apple
  • UITextFieldDelegate — cách chính để tích hợp bộ định dạng với trường văn bản
  • Khuyến nghị — sử dụng bộ định dạng cho tất cả các trường có định dạng dữ liệu cấu trúc

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.

Thảo luận dự án

Đọc thêm