UITextField là thành phần UIKit tiêu chuẩn để nhập văn bản một dòng trong iOS, kế thừa từ UIControl và hỗ trợ nhiều chế độ bàn phím. Theo tài liệu Apple Developer (2025), UITextField cung cấp delegate UITextFieldDelegate với các callback shouldBeginEditing, shouldChangeCharactersInRange và shouldReturn. Không giống như UITextView, UITextField giới hạn đầu vào ở một dòng và hỗ trợ secureTextEntry, leftView và rightView cho các điều khiển tùy chỉnh. Đây là phần tử chính cho các biểu mẫu xác thực, tìm kiếm, đăng ký và nhập dữ liệu trong ứng dụng iOS.
Những điểm chính
UITextField là một lớp của framework UIKit được thiết kế để người dùng nhập văn bản một dòng. Lớp này kế thừa từ UIControl, cho phép đăng ký các sự kiện nhập liệu thông qua cơ chế target-action: addTarget(self, action: Selector("textChanged:"), for: editingChanged). UITextField hiển thị viền (borderStyle), văn bản placeholder khi trường trống, nút xóa (clearButtonMode) và có thể chứa các view phụ trái/phải. Trường tự động hiển thị/ẩn bàn phím khi nhận/mất tiêu điểm qua becomeFirstResponder và resignFirstResponder. Kích thước trường được xác định bởi intrinsicContentSize dựa trên phông chữ và kiểu viền. Để tạo UITextField trong Interface Builder (Storyboard/XIB), sử dụng Thư viện Đối tượng; theo phương thức lập trình, sử dụng bộ khởi tạo UITextField(frame: CGRect). Lớp này hoàn toàn tương thích với kiến trúc iOS hiện đại: Combine publishers, @Published trong SwiftUI qua UIViewRepresentable và Diffable Data Source cho biểu mẫu.
UITextField hỗ trợ 12 loại bàn phím thông qua thuộc tính keyboardType. Mỗi loại tối ưu hóa bộ ký tự cho một tình huống nhập cụ thể. UIKeyboardType.default — bàn phím QWERTY tiêu chuẩn. UIKeyboardType.numberPad — chỉ chữ số không có ký tự bổ sung (lý tưởng cho mã PIN và số điện thoại). UIKeyboardType.emailAddress — bàn phím có @ và dấu chấm trên lớp chính. UIKeyboardType.URL — bàn phím có .com, / và dấu chấm trên lớp chính. UIKeyboardType.phonePad — bàn phím số với +, *, # để nhập số điện thoại. UIKeyboardType.decimalPad — chữ số với dấu thập phân để nhập giá tiền. UIKeyboardType.webSearch — bàn phím có nút Go được tối ưu cho truy vấn tìm kiếm. UIKeyboardType.asciiCapable — chỉ ký tự ASCII cho văn bản Latin. Bàn phím xuất hiện khi gọi becomeFirstResponder và ẩn khi gọi resignFirstResponder. Loại bàn phím có thể thay đổi động trong khi chỉnh sửa.
| Loại | Tình huống | Đặc điểm |
|---|---|---|
| default | Nhập văn bản chung | QWERTY tiêu chuẩn |
| numberPad | PIN, mã | Chỉ chữ số 0-9 |
| emailAddress | @ và . trên lớp chính | |
| URL | Địa chỉ web | .com, /, . trên chính |
| phonePad | Điện thoại | Chữ số, +, *, # |
| decimalPad | Giá, số | Chữ số + dấu thập phân |
UITextFieldDelegate là một giao thức xác định hành vi của trường văn bản ở các giai đoạn nhập khác nhau. Các phương thức chính: textFieldShouldBeginEditing(textField) — trả về Bool cho phép hoặc từ chối bắt đầu chỉnh sửa; textFieldDidBeginEditing — được gọi sau khi bàn phím xuất hiện; textFieldShouldEndEditing — kiểm tra xem có thể kết thúc chỉnh sửa không (nếu false, trường không mất tiêu điểm); textFieldDidEndEditing — được gọi sau khi bàn phím ẩn; textFieldShouldChangeCharactersInRange — được gọi ở mỗi lần nhập ký tự, cho phép lọc đầu vào (chỉ cho phép một ký tự, nếu trả về false — ký tự không được thêm); textFieldShouldReturn — được gọi khi nhấn Return/Go/Next/Search, dùng để chuyển đến trường tiếp theo. Delegate không phải là Optional: tất cả các phương thức đều có triển khai mặc định, nhưng để có hành vi tùy chỉnh, bạn cần ghi đè phương thức tương ứng.
Phương thức shouldReturn là mẫu tiêu chuẩn để điều hướng giữa các trường biểu mẫu. Triển khai: textFieldShouldReturn(textField) — kiểm tra textField nào đã kích hoạt sự kiện và di chuyển tiêu điểm đến trường tiếp theo qua becomeFirstResponder(). Nếu là trường cuối cùng, gọi resignFirstResponder() để ẩn bàn phím. Sử dụng IBOutlet collection hoặc các IBOutlet riêng cho mỗi trường để lưu tham chiếu đến các trường.
isSecureTextEntry — một thuộc tính UITextField mà khi true, thay thế các ký tự đã nhập bằng dấu chấm (•) và chặn sao chép văn bản qua UIMenuController. Được sử dụng cho trường mật khẩu, mã PIN, CVV. Khi chuyển đổi giữa chế độ bảo mật và văn bản thường (show/hide password), đặt textField.isSecureTextEntry.toggle(). Quan trọng: khi thay đổi isSecureTextEntry, văn bản trường bị đặt lại — hãy lưu nó trước. LeftView và RightView là các UIView tùy chỉnh được hiển thị bên trong trường nhập ở bên trái hoặc bên phải. Cách sử dụng điển hình: biểu tượng tìm kiếm trong leftView, nút "Xóa" trong rightView. Cấu hình: textField.leftViewMode = always (luôn luôn) hoặc whileEditing (chỉ khi chỉnh sửa). Các view left/right tự động được định vị bên trong trường văn bản có tính đến khoảng đệm. Kích thước view được đặt qua bounds hoặc Auto Layout.
import UIKit
class LoginViewController: UIViewController {
let passwordField = UITextField()
override func viewDidLoad() {
super.viewDidLoad()
passwordField.isSecureTextEntry = true
passwordField.placeholder = "Password"
passwordField.keyboardType = .asciiCapable
passwordField.delegate = self
// Nút hiện/ẩn mật khẩu tùy chỉnh
let showButton = UIButton(type: .system)
showButton.setTitle("Hiện", for: .normal)
showButton.addTarget(self, action: #selector(togglePasswordVisibility),
for: .touchUpInside)
passwordField.rightView = showButton
passwordField.rightViewMode = .always
}
@objc func togglePasswordVisibility() {
passwordField.isSecureTextEntry.toggle()
}
}
UITextInputTraits là một giao thức xác định giao diện trực quan và hành vi của bàn phím cho UITextField. Các thuộc tính chính: autocorrectionType (.default, .no, .yes) — bật hoặc tắt tự động sửa văn bản; autocapitalizationType (.none, .words, .sentences, .allCharacters) — tự động viết hoa cho ký tự đầu tiên; spellCheckingType — kiểm tra chính tả; returnKeyType (.done, .go, .next, .search, .send, .continue, .join, .route, .emergencyCall) — văn bản nút Return trên bàn phím; enablesReturnKeyAutomatically — tự động vô hiệu hóa nút Return khi trường trống. Đối với trường nhập tên, sử dụng autocapitalizationType = .words; cho email, sử dụng autocorrectionType = .no; cho URL, sử dụng keyboardType = .URL + autocapitalizationType = .none. Các traits được cấu hình sau khi khởi tạo trường trước khi hiển thị. Thay đổi traits động sẽ cập nhật bàn phím ở lần xuất hiện tiếp theo.
Return Key Type xác định văn bản nút trên bàn phím: Next — chuyển đến trường tiếp theo, Done — hoàn thành nhập, Search — bắt đầu tìm kiếm, Send — gửi biểu mẫu, Continue — tiếp tục điền. Kết hợp với phương thức delegate shouldReturn, returnKeyType cho phép UX tự nhiên: người dùng điền các trường, nhấn Next để chuyển đến trường tiếp theo và Done để gửi ở trường cuối cùng. Để tùy chỉnh văn bản nút, sử dụng UIButtonConfiguration trong iOS 15+.
Placeholder của UITextField là văn bản được hiển thị màu xám khi trường trống. Cấu hình: textField.placeholder = "Enter email". Để tùy chỉnh màu sắc và phông chữ của placeholder, sử dụng attributedPlaceholder với NSAttributedString. Mặt nạ nhập liệu được triển khai thông qua phương thức delegate shouldChangeCharactersInRange — hỗ trợ định dạng số điện thoại, ngày tháng, thẻ tín dụng và SNILS. Mặt nạ nhập liệu cho phép tách biệt hiển thị và giá trị: người dùng thấy văn bản đã định dạng (ví dụ: +7 (999) 999-99-99), trong khi mô hình lưu trữ "79999999999". Ví dụ triển khai: lưu trữ mặt nạ dưới dạng chuỗi với các ký tự X để thay thế; ở mỗi lần nhập, tạo chuỗi đã định dạng và trả về false trong shouldChangeCharactersInRange, thay thế văn bản trường qua textField.text = formattedText. Đối với số, sử dụng NumberFormatter và keyboardType decimal.
extension LoginViewController: UITextFieldDelegate {
func textFieldShouldReturn(
textField: UITextField
) -> Bool {
if textField == emailField {
passwordField.becomeFirstResponder()
} else if textField == passwordField {
textField.resignFirstResponder()
loginTapped()
}
return true
}
func textField(
textField: UITextField,
shouldChangeCharactersIn range: NSRange,
replacementString string: String
) -> Bool {
// Chặn khoảng trắng trong email
if textField == emailField && string == " " {
return false
}
// Giới hạn độ dài mật khẩu
if textField == passwordField {
let newLength = (textField.text?.count ?? 0) +
string.count - range.length
return newLength <= 32
}
return true
}
}
Hãy xem một ví dụ hoàn chỉnh về triển khai biểu mẫu đăng nhập với UITextField, xác thực email và phản hồi trực quan. Biểu mẫu chứa hai trường: emailField (bàn phím emailAddress, không tự động sửa) và passwordField (secureTextEntry). Xác thực được thực hiện trong shouldChangeCharactersInRange và thêm vào đó khi nhấn nút Login. Để phản hồi trực quan: viền đỏ (layer.borderColor) khi lỗi, xanh lá — khi xác thực thành công. Đặt lại viền khi bắt đầu chỉnh sửa trong textFieldDidBeginEditing.
Xác thực email được thực hiện qua NSPredicate với định dạng "SELF MATCHES %@" và biểu thức chính quy để kiểm tra định dạng cơ bản. Việc kiểm tra sự tồn tại thực tế của email nên được thực hiện trên máy chủ. Để xác thực nâng cao, sử dụng thư viện SwiftValidators hoặc Combine publishers. Ví dụ: NSPredicate(format: "SELF MATCHES [c] %@", emailRegex).evaluate(with: email). Viền trường được cập nhật qua khối hoạt ảnh để chuyển đổi mượt mà.
func validateEmail(textField: UITextField) {
guard let text = textField.text, !text.isEmpty else {
textField.layer.borderColor = UIColor.clear.cgColor
return
}
let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.\\p{L}{2,}"
let predicate = NSPredicate(format: "SELF MATCHES [c] %@", emailRegex)
let isValid = predicate.evaluate(with: text)
UIView.animate(withDuration: 0.2) {
textField.layer.borderColor = isValid
? UIColor.systemGreen.cgColor
: UIColor.systemRed.cgColor
textField.layer.borderWidth = 1.0
textField.layer.cornerRadius = 6.0
}
}
Câu hỏi thường gặp
Sử dụng phương thức delegate shouldChangeCharactersInRange. Tính độ dài văn bản mới là existingText.count + newText.count - range.length và trả về false nếu vượt quá giới hạn. Thay thế: đăng ký sự kiện editingChanged qua addTarget và cắt ngắn văn bản bằng cách sử dụng textField.text = String(text.prefix(maxLength)).
Kiểm tra: isUserInteractionEnabled = true (mặc định), delegate không trả về false trong shouldBeginEditing. Nếu trường nằm trong UIScrollView, tắt delaysContentTouches. Nếu trường trong bộ điều khiển phương thức, kiểm tra nó không chặn các chạm. Đối với SwiftUI UIViewRepresentable, kiểm tra trường trở thành firstResponder đúng cách qua DispatchQueue.main.async.
Thêm UITapGestureRecognizer trên self.view hoặc scrollView với target-action gọi view.endEditing(true). Thay thế: textField.resignFirstResponder() để ẩn bàn phím của một trường cụ thể. Triển khai touchesBegan trong UIViewController hoặc sử dụng thư viện IQKeyboardManager để quản lý bàn phím tự động. Đừng quên tắt cancelsTouchesInView để các nút hoạt động chính xác.
Màu văn bản: textField.textColor = UIColor.label. Phông chữ: textField.font = UIFont.systemFont(ofSize: 16, weight: .regular). Màu placeholder: textField.attributedPlaceholder = NSAttributedString(string: "Email", attributes: [.foregroundColor: UIColor.secondaryLabel]).
Ba cách: isEnabled = false (thay đổi giao diện), isUserInteractionEnabled = false (giữ nguyên kiểu trực quan) hoặc trả về false trong delegate textFieldShouldBeginEditing. Cách thứ ba được ưu tiên hơn — nó chặn nhập liệu mà không thay đổi kiểu trực quan. Để đặt văn bản theo phương thức lập trình ở chế độ chỉ đọc, sử dụng delegate.
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