First Responder — to obiekt UIResponder w iOS, który jako pierwszy otrzymuje zdarzenia dotknięcia, naciśnięcia klawiszy, gesty shake i polecenia menu. W każdej chwili tylko jeden obiekt w aplikacji może być first responder. Przypisanie następuje automatycznie (przy fokusie UITextField) lub programowo poprzez metodę becomeFirstResponder. Według Apple Developer Documentation (2026), obiekt może stać się first responder tylko jeśli jego metoda canBecomeFirstResponder zwraca true, co czyni ten mechanizm jawnym i kontrolowanym.
Najważniejsze
First Responder — to obiekt UIResponder, który w danym momencie przyjmuje zdarzenia wejściowe w aplikacji iOS. System kieruje wszystkie zdarzenia dotknięcia, naciśnięcia klawiszy, zdarzenia ruchu (potrząsanie urządzeniem) i komunikaty akcji (np. wywołanie menu kontekstowego) właśnie do tego obiektu.
Koncepcja first responder jest pierwszym ogniwem w Responder Chain. Jeśli first responder nie przetworzy otrzymanego zdarzenia, jest ono automatycznie przekazywane do następnego obiektu w łańcuchu. Gwarantuje to, że zdarzenie nie zostanie utracone, ale będzie kolejno proponowane wszystkim potencjalnym obsługującym w hierarchii.
Według Apple, status first responder jest ściśle powiązany z UIResponder i jego metodami canBecomeFirstResponder oraz becomeFirstResponder. Domyślnie UIView zwraca true tylko dla określonych podklas — UITextField, UITextView, UISearchBar. Inne widoki, w tym zwykły UIView, zwracają false, co zapobiega przypadkowemu przypisaniu.
Przypisanie first responder może nastąpić na dwa sposoby: automatycznie, gdy użytkownik dotknie UITextField (system wywołuje becomeFirstResponder wewnętrznie), lub programowo, gdy deweloper jawnie wywołuje metodę becomeFirstResponder na dowolnym obiekcie UIResponder.
Przed przypisaniem iOS sprawdza canBecomeFirstResponder. Jeśli metoda zwraca false, wywołanie becomeFirstResponder jest ignorowane, a obiekt nie staje się first responder. Jest to mechanizm ochronny zapobiegający przypisaniu obiektów, które nie są gotowe do obsługi zdarzeń — na przykład ukrytych lub wyłączonych elementów interfejsu.
class CustomTextField: UITextField {
override var canBecomeFirstResponder: Bool {
return super.canBecomeFirstResponder
}
}
// Przypisanie programowe
textField.becomeFirstResponder()
// Sprawdź, czy first responder
if textField.isFirstResponder {
print("TextField jest teraz first responder")
}
Przy przypisaniu nowego first responder iOS automatycznie wywołuje resignFirstResponder u poprzedniego. Gwarantuje to, że w systemie zawsze tylko jeden obiekt ma status first responder. Jeśli nowy obiekt nie może stać się first responder (canBecomeFirstResponder = false), stary zachowuje swój status.
Klawiatura iOS pojawia się na ekranie właśnie dzięki mechanizmowi first responder. Gdy UITextField lub UITextView staje się first responder, system automatycznie wyświetla klawiaturę powiązaną z bieżącym keyboardType tego pola. Przy resign first responder klawiatura jest ukrywana.
To zachowanie jest kluczowym mechanizmem UX w iOS: użytkownik dotyka pola wprowadzania — klawiatura się pojawia; naciska Return lub dotyka innego pola — klawiatura przełącza się lub ukrywa. Deweloper może zarządzać tym poprzez metody UIResponder, a także przez inputView i inputAccessoryView w celu zastąpienia standardowej klawiatury niestandardową.
Input Accessory View — to dodatkowy panel nad klawiaturą, który również jest powiązany z first responder. Na przykład panel z przyciskami Next, Previous, Done do nawigacji między polami wprowadzania. Jest wyświetlany i ukrywany razem z klawiaturą, synchronizując się ze statusem first responder.
| Zdarzenie | Status first responder | Klawiatura |
|---|---|---|
| Dotknięcie UITextField | Staje się first responder | Pojawia się |
| Naciśnięcie Return | Pozostaje lub rezygnuje | Pozostaje lub ukrywa się |
| Dotknięcie innego pola | Przechodzi do nowego pola | Przełącza się |
| Wywołanie resignFirstResponder | Usunięty | Ukrywa się |
| Ukrycie aplikacji | Automatycznie rezygnuje | Ukrywa się |
ResignFirstResponder — to metoda UIResponder, która usuwa z obiektu status first responder. Po wywołaniu obiekt przestaje otrzymywać zdarzenia wejściowe, a klawiatura (jeśli była aktywna) jest ukrywana. Metoda zwraca Bool — true, jeśli rezygnacja przebiegła pomyślnie.
Deweloperzy często wywołują resignFirstResponder w odpowiedzi na naciśnięcie przycisku Done, dotknięcie pustego obszaru ekranu (view.endEditing) lub przy opuszczaniu ekranu. view.endEditing(true) — to wygodny sposób rezygnacji dla wszystkich podrzędnych pól tekstowych naraz: przechodzi przez całą hierarchię widoków i wywołuje resignFirstResponder u bieżącego first responder.
// Rezygnacja po naciśnięciu Done
@objc func doneButtonTapped() {
textField.resignFirstResponder()
}
// Rezygnacja po dotknięciu pustego obszaru
override func touchesBegan(
_ touches: Set<UITouch>,
with event: UIEvent?
) {
view.endEditing(true)
}
// Rezygnacja dla wszystkich pól formularza
func validateAndSubmit() {
view.endEditing(true)
// Logika przesyłania formularza
}
Istnieją sytuacje, w których resignFirstResponder może zwrócić false. Dzieje się tak, jeśli obiekt nadpisał metodę i jawnie zabronił usunięcia statusu. Na przykład pole tekstowe w trakcie walidacji może tymczasowo blokować rezygnację, aby zapobiec utracie danych. W takich przypadkach należy poczekać na zakończenie walidacji i dopiero wtedy wymusić rezygnację.
UIResponder udostępnia właściwość isFirstResponder (tylko do odczytu), która zwraca true, jeśli dany obiekt w danym momencie jest first responder. Jest to przydatne do logiki warunkowej — na przykład, aby nie wykonywać akcji, jeśli pole tekstowe jest w fokusie i użytkownik wprowadza dane.
iOS nie udostępnia wbudowanego API do uzyskania bieżącego first responder w skali całej aplikacji. Deweloperzy tworzą tę możliwość poprzez przejście hierarchii widoków za pomocą metody UIResponder. Rozwiązanie Apple zaleca słabe odwołanie do first responder, które można aktualizować przez KVO lub delegatów.
// Rozszerzenie do znajdowania first responder
extension UIView {
var firstResponder: UIResponder? {
guard isFirstResponder else {
return subviews.compactMap { $0.firstResponder }.first
}
return self
}
}
// Użycie
if let current = view.firstResponder {
print("Current first responder: \(current)")
}
Do śledzenia zmian first responder można zasubskrybować powiadomienia UIResponder.keyboardWillShowNotification i UIResponder.keyboardWillHideNotification — pośrednio wskazują one, że jakiś obiekt tekstowy stał się lub przestał być first responder. Nie istnieje jednak bezpośrednia subskrypcja zmiany isFirstResponder; do tego celu używa się KVO lub niestandardowych delegatów.
Niestandardowe widoki mogą stać się first responder, jeśli nadpiszą canBecomeFirstResponder i zwrócą true. Jest to niezbędne dla komponentów, które powinny przyjmować zdarzenia klawiatury lub fizycznych przycisków — na przykład niestandardowe kontrolery gier lub edytory kodu oparte na UITextView.
Przy tworzeniu niestandardowego first responder ważne jest pamiętanie o dostępności: VoiceOver i Switch Control polegają na prawidłowym przypisaniu first responder do nawigacji. Jeśli niestandardowy widok staje się first responder, powinien poprawnie zaimplementować protokół UIAccessibility i informować technologie asystujące o swoim statusie.
Do niestandardowego wprowadzania (na przykład skanera kodów kreskowych lub klawiatury numerycznej) nadpisz właściwość inputView — zwróć niestandardowy UIView, który będzie wyświetlany zamiast standardowej klawiatury, gdy ten widok jest first responder. Analogicznie, inputAccessoryView dodaje panel nad klawiaturą.
Często zadawane pytania
First Responder — to obiekt UIResponder, który w danym momencie otrzymuje zdarzenia wejściowe (dotknięcia, klawisze, akcelerometr). Jest przypisywany przez becomeFirstResponder, musi zwracać true z canBecomeFirstResponder. Tylko jeden obiekt może być first responder w aplikacji.
Wywołaj textField.becomeFirstResponder() programowo, na przykład w viewDidAppear. Upewnij się, że textField nie jest ukryty, userInteractionEnabled = true, a isEnabled = true. Jeśli pole znajduje się w UITableView lub UICollectionView, upewnij się, że komórka jest widoczna na ekranie.
Dodaj UITapGestureRecognizer do głównego widoku i w jego obsłudze wywołaj view.endEditing(true). To automatycznie znajdzie bieżący first responder i wywoła resignFirstResponder. Alternatywnie nadpisz touchesBegan w UIViewController z wywołaniem endEditing.
becomeFirstResponder zwraca false, jeśli canBecomeFirstResponder zwraca false, widok jest ukryty, nie ma w hierarchii okna lub userInteractionEnabled = false. Sprawdź również, czy widok został dodany do okna — widok, który nie znajduje się na ekranie, nie zadziała z becomeFirstResponder.
iOS nie udostępnia globalnego API do tego celu. Użyj rekurencyjnego przejścia hierarchii widoków poprzez rozszerzenie UIView, które sprawdza isFirstResponder u każdego subview. Alternatywa — przechowuj słabe odwołanie do ostatniego first responder w AppDelegate i aktualizuj je przez delegatów UITextField.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również