First Responder — це об’єкт UIResponder в iOS, який першим отримує події дотику, натискання клавіш, жестив струшування та команд меню. В кожний момент часу тільки один об’єкт в додатку може бути first responder. Призначення відбувається автоматично (при фокусі UITextField) або програмно через метод becomeFirstResponder. За даними Документації Розробника Apple (2026), об’єкт може стати first responder тільки якщо його метод canBecomeFirstResponder повертає true, що робить цей механізм явним та керованим.
Головне
First Responder — це об’єкт UIResponder, який наразі приймає події введення в iOS-додатку. Система направляє всі події дотику, натискання клавіш, події руху (струшування пристрою) та повідомлення дії (наприклад, виклик контекстного меню) саме цьому об’єкту.
Концепція first responder є першою ланкою в Responder Chain. Якщо first responder не обробляє отриману подію, вона автоматично передається наступному об’єкту в ланцюзі. Це гарантує, що подія не загубиться, а буде послідовно запропонована всім потенційним обробникам в ієрархії.
За даними Apple, статус first responder тісно пов’язаний з UIResponder та його методами canBecomeFirstResponder та becomeFirstResponder. Типово UIView повертає true тільки для певних підкласів — UITextField, UITextView, UISearchBar. Інші view, включаючи звичайний UIView, повертають false, що запобігає випадковому призначенню.
Призначення first responder може відбуватися двома способами: автоматично, коли користувач торкається UITextField (система викликає becomeFirstResponder внутрішньо), або програмно, коли розробник явно викликає метод becomeFirstResponder на будь-якому об’єкті UIResponder.
Перед призначенням iOS перевіряє canBecomeFirstResponder. Якщо метод повертає false, виклик becomeFirstResponder ігнорується, і об’єкт не стає first responder. Це захисний механізм, що запобігає призначенню об’єктів, які не готові обробляти події — наприклад, прихованих або вимкнених елементів інтерфейсу.
class CustomTextField: UITextField {
override var canBecomeFirstResponder: Bool {
return super.canBecomeFirstResponder
}
}
// Програмне призначення
textField.becomeFirstResponder()
// Перевірка чи є first responder
if textField.isFirstResponder {
print("TextField тепер first responder")
}
При призначенні нового first responder iOS автоматично викликає resignFirstResponder у попереднього. Це гарантує, що в системі завжди лише один об’єкт із статусом first responder. Якщо новий об’єкт не може стати first responder (canBecomeFirstResponder = false), старий зберігає свій статус.
Клавіатура iOS з’являється на екрані саме завдяки механізму first responder. Коли UITextField або UITextView стає first responder, система автоматично відображає клавіатуру, пов’язану з поточним keyboardType цього поля. При resign first responder клавіатура ховається.
Ця поведінка є ключовим UX-механізмом в iOS: користувач торкається поля введення — клавіатура з’являється; натискає Return або торкається іншого поля — клавіатура перемикається або ховається. Розробник може керувати цим через методи UIResponder, а також через inputView та inputAccessoryView для заміни стандартної клавіатури на кастомну.
Input Accessory View — це додаткова панель над клавіатурою, яка також прив’язана до first responder. Наприклад, панель з кнопками Далі, Назад, Готово для навігації між полями введення. Вона з’являється та ховається разом з клавіатурою, синхронізуючись зі статусом first responder.
| Подія | Статус first responder | Клавіатура |
|---|---|---|
| Дотик UITextField | Стає first responder | З’являється |
| Натиск Return | Залишається або resign | Залишається або ховається |
| Дотик іншого поля | Переходить до нового поля | Перемикається |
| Виклик resignFirstResponder | Знімається | Ховається |
| Приховання додатка | Автоматично resign | Ховається |
ResignFirstResponder — це метод UIResponder, який знімає з об’єкта статус first responder. Після виклику об’єкт перестає отримувати події введення, а клавіатура (якщо була активна) ховається. Метод повертає Bool — true, якщо resign пройшов успішно.
Розробники часто викликають resignFirstResponder у відповідь на натиск кнопки Готово, дотик порожньої області екрану (view.endEditing) або при виході з екрану. view.endEditing(true) — зручний спосіб resign для всіх дочірних текстових полів одразу: він проходить по всій ієрархії view та викликає resignFirstResponder у поточного first responder.
// Resign при натисканні Готово
@objc func doneButtonTapped() {
textField.resignFirstResponder()
}
// Resign при дотику порожньої області
override func touchesBegan(
_ touches: Set<UITouch>,
with event: UIEvent?
) {
view.endEditing(true)
}
// Resign для всіх полів форми
func validateAndSubmit() {
view.endEditing(true)
// Логіка відправлення форми
}
Існують ситуації, коли resignFirstResponder може повернути false. Це відбувається, якщо об’єкт перевизначив метод та явно заборонив зняття статусу. Наприклад, текстове поле в процесі валідації може тимчасово блокувати resign, щоб запобігти втраті даних. У таких випадках необхідно дочекатися завершення валідації і тільки потім примусово resign.
UIResponder надає властивість isFirstResponder (тільки читання), яка повертає true, якщо даний об’єкт наразі є first responder. Це корисно для умовної логіки — наприклад, щоб не виконувати дію, якщо текстове поле в фокусі та користувач вводить дані.
iOS не надає вбудованого API для отримання поточного first responder в масштабі всього додатка. Розробники створюють цю можливість через обхід ієрархії view за допомогою методу UIResponder. Apple рекомендує слабке посилання на first responder, яке можна оновлювати через KVO або делегати.
// Розширення для пошуку first responder
extension UIView {
var firstResponder: UIResponder? {
guard isFirstResponder else {
return subviews.compactMap { $0.firstResponder }.first
}
return self
}
}
// Використання
if let current = view.firstResponder {
print("Current first responder: \(current)")
}
Для відстеження змін first responder можна підписатися на UIResponder.keyboardWillShowNotification та UIResponder.keyboardWillHideNotification — вони непрямо вказують, що якийсь текстовий об’єкт став або перестав бути first responder. Однак прямої підписки на зміну isFirstResponder не існує; для цього використовується KVO або кастомні делегати.
Кастомні view можуть стати first responder, якщо перевизначити canBecomeFirstResponder та повернути true. Це необхідно для компонентів, які повинні приймати події клавіатури або фізичних кнопок — наприклад, кастомні ігрові контролери або редактори коду на основі UITextView.
При створенні кастомного first responder важливо пам’ятати про доступність: VoiceOver та Switch Control покладаються на правильне призначення first responder для навігації. Якщо кастомна view стає first responder, вона повинна коректно реалізувати протокол UIAccessibility та повідомляти асистивним технологіям про свій статус.
Для кастомного введення (наприклад, сканера штрихкодів або цифрової клавіатури) перевизначте властивість inputView — поверніть кастомну UIView, яка буде відображатися замість стандартної клавіатури, коли ця view є first responder. Аналогічно, inputAccessoryView додає панель над клавіатурою.
Часто задавані питання
First Responder — це об’єкт UIResponder, який наразі отримує події введення (дотики, клавіші, акселерометр). Призначається через becomeFirstResponder, повинен повертати true з canBecomeFirstResponder. Тільки один об’єкт може бути first responder в додатку.
Викличіть textField.becomeFirstResponder() програмно, наприклад, в viewDidAppear. Переконайтеся, що textField не прихований, userInteractionEnabled = true та isEnabled = true. Якщо поле знаходиться в UITableView або UICollectionView, переконайтеся, що комірка видна на екрані.
Додайте UITapGestureRecognizer на основну view та в його обробнику викличіть view.endEditing(true). Це автоматично знайде поточний first responder та викличе resignFirstResponder. Або перевизначте touchesBegan у UIViewController з викликом endEditing.
becomeFirstResponder повертає false, якщо canBecomeFirstResponder повертає false, view прихована, не в ієрархії вікна або userInteractionEnabled = false. Також перевірте, що view додана до вікна — view, яка не на екрані, не спрацює з becomeFirstResponder.
iOS не надає глобального API для цього. Використовуйте рекурсивний обхід view hierarchy через розширення UIView, яке перевіряє isFirstResponder у кожного subview. Альтернатива — зберігати слабке посилання на останній first responder в AppDelegate та оновлювати його через делегати UITextField.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також