First Responder là đối tượng UIResponder trong iOS nhận đầu tiên các sự kiện chạm, nhấn phím, cử chỉ lắc và lệnh menu. Tại bất kỳ thời điểm nào, chỉ một đối tượng trong ứng dụng có thể là first responder. Việc chỉ định xảy ra tự động (khi UITextField nhận tiêu điểm) hoặc theo chương trình thông qua phương thức becomeFirstResponder. Theo Tài liệu Nhà phát triển Apple (2026), một đối tượng chỉ có thể trở thành first responder nếu phương thức canBecomeFirstResponder của nó trả về true, làm cho cơ chế này trở nên rõ ràng và có thể kiểm soát.
Ý chính
First Responder là đối tượng UIResponder hiện đang nhận các sự kiện đầu vào trong ứng dụng iOS. Hệ thống gửi tất cả các sự kiện chạm, nhấn phím, sự kiện chuyển động (lắc thiết bị) và thông báo hành động (ví dụ: gọi menu ngữ cảnh) đến đối tượng này.
Khái niệm first responder là mắt xích đầu tiên trong Chuỗi phản hồi (Responder Chain). Nếu first responder không xử lý một sự kiện nhận được, nó sẽ tự động được chuyển đến đối tượng tiếp theo trong chuỗi. Điều này đảm bảo rằng một sự kiện không bị mất mà được đề xuất tuần tự cho tất cả các trình xử lý tiềm năng trong hệ phân cấp.
Theo Apple, trạng thái first responder được liên kết chặt chẽ với UIResponder và các phương thức canBecomeFirstResponder và becomeFirstResponder của nó. Theo mặc định, UIView trả về true chỉ cho một số lớp con nhất định — UITextField, UITextView, UISearchBar. Các view khác, bao gồm UIView thông thường, trả về false, ngăn chặn việc chỉ định ngẫu nhiên.
Việc chỉ định first responder có thể xảy ra theo hai cách: tự động, khi người dùng chạm vào UITextField (hệ thống gọi becomeFirstResponder nội bộ), hoặc theo chương trình, khi nhà phát triển gọi rõ ràng phương thức becomeFirstResponder trên bất kỳ đối tượng UIResponder nào.
Trước khi chỉ định, iOS kiểm tra canBecomeFirstResponder. Nếu phương thức trả về false, lời gọi becomeFirstResponder bị bỏ qua và đối tượng không trở thành first responder. Đây là cơ chế bảo vệ ngăn chặn việc chỉ định các đối tượng chưa sẵn sàng xử lý sự kiện — ví dụ, các phần tử giao diện bị ẩn hoặc vô hiệu hóa.
class CustomTextField: UITextField {
override var canBecomeFirstResponder: Bool {
return super.canBecomeFirstResponder
}
}
// Gán theo chương trình
textField.becomeFirstResponder()
// Kiểm tra xem có phải first responder
if textField.isFirstResponder {
print("TextField hiện là first responder")
}
Khi một first responder mới được chỉ định, iOS tự động gọi resignFirstResponder trên đối tượng trước đó. Điều này đảm bảo rằng luôn chỉ có một đối tượng với trạng thái first responder trong hệ thống. Nếu đối tượng mới không thể trở thành first responder (canBecomeFirstResponder = false), đối tượng cũ giữ nguyên trạng thái của nó.
Bàn phím iOS xuất hiện trên màn hình chính nhờ cơ chế first responder. Khi UITextField hoặc UITextView trở thành first responder, hệ thống tự động hiển thị bàn phím liên kết với keyboardType hiện tại của trường đó. Khi first responder resign, bàn phím sẽ ẩn đi.
Hành vi này là một cơ chế UX chính trong iOS: người dùng chạm vào trường nhập — bàn phím xuất hiện; nhấn Return hoặc chạm vào trường khác — bàn phím chuyển đổi hoặc ẩn đi. Nhà phát triển có thể kiểm soát điều này thông qua các phương thức UIResponder, cũng như thông qua inputView và inputAccessoryView để thay thế bàn phím tiêu chuẩn bằng bàn phím tùy chỉnh.
Input Accessory View là một bảng điều khiển bổ sung phía trên bàn phím cũng được liên kết với first responder. Ví dụ, một bảng với các nút Tiếp theo, Trước, Xong để di chuyển giữa các trường nhập. Nó xuất hiện và ẩn đi cùng với bàn phím, đồng bộ với trạng thái first responder.
| Sự kiện | Trạng thái first responder | Bàn phím |
|---|---|---|
| Chạm UITextField | Trở thành first responder | Xuất hiện |
| Nhấn Return | Ở lại hoặc resign | Ở lại hoặc ẩn |
| Chạm trường khác | Chuyển đến trường mới | Chuyển đổi |
| Gọi resignFirstResponder | Bị xóa | Ẩn |
| Ứng dụng bị ẩn | Tự động resign | Ẩn |
ResignFirstResponder là một phương thức UIResponder xóa trạng thái first responder khỏi một đối tượng. Sau khi gọi, đối tượng ngừng nhận các sự kiện đầu vào và bàn phím (nếu đang hoạt động) sẽ ẩn đi. Phương thức trả về một Bool — true nếu resign thành công.
Các nhà phát triển thường gọi resignFirstResponder để phản hồi khi nhấn nút Xong, chạm vào vùng trống của màn hình (view.endEditing), hoặc khi rời khỏi màn hình. view.endEditing(true) là một cách thuận tiện để resign cho tất cả các trường văn bản con cùng một lúc: nó duyệt toàn bộ hệ phân cấp view và gọi resignFirstResponder trên first responder hiện tại.
// Resign khi nhấn nút Xong
@objc func doneButtonTapped() {
textField.resignFirstResponder()
}
// Resign khi chạm vùng trống
override func touchesBegan(
_ touches: Set<UITouch>,
with event: UIEvent?
) {
view.endEditing(true)
}
// Resign cho tất cả trường biểu mẫu
func validateAndSubmit() {
view.endEditing(true)
// Logic gửi biểu mẫu
}
Có những tình huống resignFirstResponder có thể trả về false. Điều này xảy ra nếu đối tượng đã ghi đè phương thức và rõ ràng ngăn chặn việc xóa trạng thái. Ví dụ, một trường văn bản đang trong quá trình xác thực có thể tạm thời chặn resign để tránh mất dữ liệu. Trong những trường hợp này, hãy chờ cho đến khi xác thực hoàn tất rồi mới resign cưỡng bức.
UIResponder cung cấp thuộc tính isFirstResponder (chỉ đọc), trả về true nếu đối tượng được chỉ định hiện là first responder. Điều này hữu ích cho logic có điều kiện — ví dụ, để tránh thực hiện một hành động nếu trường văn bản đang được tiêu điểm và người dùng đang nhập dữ liệu.
iOS không cung cấp API tích hợp để lấy first responder hiện tại trên phạm vi toàn ứng dụng. Các nhà phát triển đạt được điều này bằng cách duyệt hệ phân cấp view thông qua phương thức UIResponder. Apple khuyến nghị một tham chiếu yếu (weak reference) đến first responder, có thể được cập nhật qua KVO hoặc ủy quyền.
// Mở rộng để tìm first responder
extension UIView {
var firstResponder: UIResponder? {
guard isFirstResponder else {
return subviews.compactMap { $0.firstResponder }.first
}
return self
}
}
// Cách sử dụng
if let current = view.firstResponder {
print("Current first responder: \(current)")
}
Để theo dõi các thay đổi của first responder, bạn có thể đăng ký UIResponder.keyboardWillShowNotification và UIResponder.keyboardWillHideNotification — chúng chỉ ra một cách gián tiếp rằng một đối tượng văn bản nào đó đã trở thành hoặc ngừng là first responder. Tuy nhiên, không có đăng ký trực tiếp cho các thay đổi của isFirstResponder; thay vào đó, KVO hoặc ủy quyền tùy chỉnh được sử dụng.
Các view tùy chỉnh có thể trở thành first responder nếu chúng ghi đè canBecomeFirstResponder và trả về true. Điều này cần thiết cho các thành phần cần nhận sự kiện bàn phím hoặc nút vật lý — ví dụ, bộ điều khiển trò chơi tùy chỉnh hoặc trình chỉnh sửa mã dựa trên UITextView.
Khi tạo một first responder tùy chỉnh, điều quan trọng là phải xem xét khả năng tiếp cận: VoiceOver và Switch Control phụ thuộc vào việc chỉ định first responder chính xác để điều hướng. Nếu một view tùy chỉnh trở thành first responder, nó phải triển khai đúng giao thức UIAccessibility và báo cáo trạng thái của nó cho các công nghệ hỗ trợ.
Để nhập tùy chỉnh (ví dụ, máy quét mã vạch hoặc bàn phím số), hãy ghi đè thuộc tính inputView — trả về một UIView tùy chỉnh sẽ được hiển thị thay vì bàn phím tiêu chuẩn khi view này là first responder. Tương tự, inputAccessoryView thêm một bảng điều khiển phía trên bàn phím.
Câu hỏi thường gặp
First Responder là đối tượng UIResponder hiện đang nhận các sự kiện đầu vào (chạm, phím, gia tốc kế). Nó được chỉ định qua becomeFirstResponder và phải trả về true từ canBecomeFirstResponder. Chỉ một đối tượng có thể là first responder trong một ứng dụng.
Gọi textField.becomeFirstResponder() theo chương trình, ví dụ, trong viewDidAppear. Đảm bảo textField không bị ẩn, userInteractionEnabled = true, và isEnabled = true. Nếu trường nằm trong UITableView hoặc UICollectionView, hãy đảm bảo ô có thể nhìn thấy trên màn hình.
Thêm UITapGestureRecognizer vào view chính và gọi view.endEditing(true) trong trình xử lý của nó. Thao tác này sẽ tự động tìm first responder hiện tại và gọi resignFirstResponder. Ngoài ra, hãy ghi đè touchesBegan trong UIViewController với lời gọi endEditing.
becomeFirstResponder trả về false nếu canBecomeFirstResponder trả về false, view bị ẩn, không nằm trong hệ phân cấp cửa sổ, hoặc userInteractionEnabled = false. Cũng kiểm tra xem view đã được thêm vào cửa sổ chưa — một view không có trên màn hình sẽ không phản hồi với becomeFirstResponder.
iOS không cung cấp API toàn cục cho việc này. Sử dụng duyệt đệ quy hệ phân cấp view thông qua mở rộng UIView kiểm tra isFirstResponder trên mỗi subview. Một phương án thay thế là lưu một tham chiếu yếu đến first responder cuối cùng trong AppDelegate và cập nhật nó thông qua ủy quyền UITextField.
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