Responder Chain: co to jest, zasada działania i łańcuch responderów

Autor: IT Sectr Opublikowano: 2026-07-09 Czas czytania: 9 min

Responder Chain to mechanizm iOS, który sekwencyjnie przekazuje zdarzenia dotyku, naciśnięcia klawiszy i gestów przez hierarchię obiektów UIResponder, aż jeden z nich nie przetworzy zdarzenia. Łańcuch rozpoczyna się od obiektu, który wykrył zdarzenie, i przesuwa się w górę hierarchii: od widoku do jego superview, następnie do view controller, window i w końcu do UIApplication. Według Apple Developer Documentation (2026), ten wzorzec pozwala rozdzielić odpowiedzialność za obsługę zdarzeń między komponentami interfejsu, zapewniając elastyczność bez sztywnego wiązania z konkretnym handlerem.

Najważniejsze

  • Responder Chain to hierarchiczny łańcuch obiektów UIResponder do sekwencyjnego przekazywania zdarzeń od pierwszego respondera do UIApplication.
  • Hit-Testing określa, który obiekt stanie się pierwszym w łańcuchu responderów, analizując zagnieżdżenie widoku w punkcie dotyku.
  • Każdy UIResponder może przetworzyć zdarzenie lub przekazać je dalej wzdłuż łańcucha za pośrednictwem metody next.
  • UIApplication to końcowy węzeł łańcucha: jeśli żaden obiekt nie przetworzył zdarzenia, jest ono odrzucane.
  • Niestandardowe handler są tworzone przez nadpisanie metod touchesBegan, touchesMoved, touchesEnded w podklasach UIView lub UIViewController.

Czym jest Responder Chain

Responder Chain to sekwencja obiektów UIResponder, przez które iOS przekazuje zdarzenia wejściowe, takie jak dotknięcia, naciśnięcia klawiszy i akcelerometr. Każdy obiekt w tym łańcuchu ma możliwość przetworzenia zdarzenia lub przekazania go następnemu obiektowi responder za pośrednictwem właściwości next.

Mechanizm opiera się na hierarchii widoków: gdy nastąpi dotknięcie, iOS najpierw określa, który widok został naciśnięty (poprzez hit-testing), i tworzy łańcuch rozpoczynający się od tego widoku i wznoszący się do UIApplication. UIApplication jest ostatnim ogniwem łańcucha — jeśli zdarzenie dotrze do niego i nie zostanie przetworzone, jest po prostu odrzucane.

Według Apple, ten wzorzec jest krytycznie ważny dla enkapsulacji logiki obsługi zdarzeń. Deweloper może nadpisać zachowanie konkretnego widoku, nie wpływając na pozostałe elementy hierarchii. Na przykład UITextField staje się first responder po uzyskaniu fokusu i otrzymuje zdarzenia klawiatury, nie wymagając zmian w nadrzędnym UIViewController.

Jak Responder Chain przetwarza zdarzenia

Przetwarzanie zdarzeń przez Responder Chain odbywa się w dwóch etapach: najpierw iOS określa, który widok otrzymał zdarzenie (hit-testing), następnie uruchamia łańcuch responderów w celu jego obsługi. Jeśli obiekt nie implementuje odpowiedniej metody, zdarzenie jest przekazywane dalej.

Łańcuch jest tworzony dynamicznie na podstawie bieżącego first responder i hierarchii widoków. Standardowa kolejność wygląda następująco: first responder → jego widok → superview → UIViewController → root view → UIWindow → UIApplication. Jeśli którykolwiek z tych obiektów implementuje na przykład touchesBegan, zdarzenie jest przetwarzane na tym poziomie i nie jest przekazywane dalej.

swift
import UIKit

class CustomView: UIView {
    override func touchesBegan(
        _ touches: Set<UITouch>,
        with event: UIEvent?
    ) {
        // Dotknięcie obsłużone na tym poziomie widoku
        print("CustomView obsłużył dotknięcie")
        
        // Przekaż zdarzenie wzdłuż łańcucha
        super.touchesBegan(touches, with: event)
    }
}

Kluczową cechą jest to, że wywołanie super.touchesBegan nie jest obowiązkowe. Jeśli nie zostanie wywołane, zdarzenie zostanie przetworzone tylko na bieżącym poziomie i nie będzie kontynuować wzdłuż Responder Chain. Daje to deweloperowi pełną kontrolę nad tym, które obiekty uczestniczą w przetwarzaniu.

Przekazywanie zdarzeń między obiektami responder

Gdy obiekt otrzymuje zdarzenie, ale go nie przetwarza (nie nadpisuje metody), iOS automatycznie przekazuje zdarzenie następnemu obiektowi responder za pośrednictwem właściwości next. Ta właściwość tworzy listę jednokierunkową, która nazywa się Responder Chain.

UIViewController znajduje się pomiędzy swoim widokiem a UIWindow: jeśli widok nie przetwarza zdarzenia, kontroler otrzymuje szansę, aby to zrobić. Jest to szczególnie przydatne dla wspólnej logiki — na przykład obsługi gestu, który powinien działać na całej scenie, niezależnie od tego, który widok znajduje się pod palcem użytkownika.

Hit-Testing: od dotyku do pierwszego respondera

Hit-Testing to proces, za pomocą którego iOS określa, który widok znajduje się pod punktem dotyku. Metoda hitTest:withEvent: przegląda hierarchię widoków od UIWindow w dół, sprawdzając, który z widoków potomnych zawiera punkt dotyku i nie jest ukryty.

Algorytm działa rekurencyjnie: dla każdego poziomu iOS sprawdza widoki w odwrotnej kolejności dodawania (najpierw górne). Jeśli widok nie jest ukryty, nie jest przezroczysty, a punkt mieści się w jego bounds, uruchamiany jest hitTest rekurencyjnie dla wszystkich subviews. Najgłębszy widok spełniający wszystkie warunki staje się hit-test view — pierwszym obiektem w Responder Chain.

swift
override func hitTest(
    _ point: CGPoint,
    with event: UIEvent?
) -> UIView? {
    if isUserInteractionEnabled &&
        isHidden == false &&
        alpha > 0.01 &&
        point(inside: point, with: event) {
        return super.hitTest(point, with: event)
    }
    return nil
}

Deweloperzy mogą nadpisać hitTest, aby zmienić standardowe zachowanie. Na przykład rozszerzyć obszar dotyku dla małego przycisku lub przekierować zdarzenie na inny widok, który fizycznie nie znajduje się pod palcem. Jest to potężne narzędzie do tworzenia niestandardowych elementów interaktywnych.

Metody UIResponder dla łańcucha responderów

UIResponder to klasa bazowa dla wszystkich obiektów, które mogą przetwarzać zdarzenia w iOS. UIView, UIViewController, UIApplication i UIWindow dziedziczą po UIResponder. Klasa udostępnia zestaw metod, które można nadpisać w celu obsługi różnych typów zdarzeń.

Główne grupy metod obejmują touchesBegan, touchesMoved, touchesEnded, touchesCancelled dla dotknięć; pressesBegan, pressesEnded dla przycisków fizycznych; oraz motionBegan, motionEnded dla zdarzeń akcelerometru. Każda metoda otrzymuje zestaw obiektów UITouch lub UIPress oraz referencję do UIEvent zawierającego dodatkowe metadane o zdarzeniu.

Metoda UIResponderPrzeznaczenie
touchesBeganWywoływana na początku dotknięcia
touchesMovedWywoływana przy przesuwaniu palca
touchesEndedWywoływana przy puszczeniu palca
touchesCancelledWywoływana przy przerwaniu (połączenie, przesunięcie zasłony)
pressesBeganWywoływana przy naciśnięciu przycisku fizycznego

Ważne jest, aby zrozumieć, że iOS wywołuje te metody tylko dla first responder i kolejnych obiektów w łańcuchu. Jeśli żaden obiekt nie nadpisał metody, zdarzenie nie generuje błędu — jest po prostu ignorowane. Do debugowania obsługi zdarzeń użyj Symbolic Breakpoint na UIResponder touchEvent.

Responder Chain a elementy UIKit

Standardowe komponenty UIKit aktywnie wykorzystują Responder Chain do swojej pracy. UITextField staje się first responder po uzyskaniu fokusu, co automatycznie otwiera klawiaturę. UIButton obsługuje dotknięcia poprzez mechanizm UIControl, który również opiera się na responder chain.

UITableView i UICollectionView używają łańcucha responderów do obsługi zaznaczania komórek i gestów przewijania. Jeśli użytkownik dotyka komórki, zdarzenie najpierw otrzymuje sama komórka, następnie UITableView, a dopiero potem UIViewController. UIGestureRecognizer ma wyższy priorytet niż touchesBegan — jeśli do widoku dodano rozpoznawacz gestów, otrzyma on zdarzenie jako pierwszy.

Według Apple, prawidłowe użycie Responder Chain jest krytycznie ważne dla dostępności aplikacji. VoiceOver i inne technologie asystujące używają łańcucha responderów do nawigacji między elementami interfejsu. Jeśli łańcuch jest przerwany, użytkownicy z niepełnosprawnościami nie będą mogli wchodzić w interakcję z aplikacją.

UIMenuController a Responder Chain

UIMenuController do wyświetlania menu kontekstowego również używa Responder Chain. Gdy użytkownik wywołuje menu, system szuka first respondera, który implementuje metody canPerformAction i odpowiednie metody akcji. Menu jest wyświetlane tylko dla tych działań, które obsługuje bieżący responder.

Pozwala to na przykład pokazywać polecenia Wytnij, Kopiuj, Wklej tylko wtedy, gdy UITextField jest w fokusie, i ukrywać je podczas pracy z UILabel. Deweloper może dodać niestandardowe działania do menu kontekstowego, implementując je w podklasie UIResponder i zwracając true z canPerformAction.

Niestandardowe obiekty responder w iOS

Tworzenie niestandardowego obiektu responder daje deweloperowi pełną kontrolę nad obsługą zdarzeń. W tym celu należy utworzyć podklasę UIResponder (lub UIView/UIViewController) i nadpisać niezbędne metody obsługi zdarzeń.

Często niestandardowe obiekty responder są używane do obsługi specyficznych gestów, które nie są pokrywane przez standardowe UIGestureRecognizer. Na przykład rozpoznawanie rysowania kształtów, złożonych kombinacji multi-touch lub zastrzeżonych wzorców wprowadzania. Niestandardowy responder może agregować zdarzenia z wielu palców i podejmować decyzję na podstawie ich kombinacji.

swift
class DrawingResponder: UIResponder {
    private var activeTouches: [UITouch: CGPoint] = [:]
    
    override func touchesBegan(
        _ touches: Set<UITouch>,
        with event: UIEvent?
    ) {
        for touch in touches {
            activeTouches[touch] = touch.location(in: self)
        }
    }
    
    override func touchesMoved(
        _ touches: Set<UITouch>,
        with event: UIEvent?
    ) {
        for touch in touches {
            let currentPoint = touch.location(in: self)
            activeTouches[touch] = currentPoint
            drawLine(from: activeTouches[touch]!, to: currentPoint)
        }
    }
}

Podczas tworzenia niestandardowego respondera ważne jest prawidłowe skonfigurowanie łańcucha next. Jeśli twój obiekt nie jest częścią standardowej hierarchii UIKit, należy jawnie określić, który obiekt będzie jego next responder. Gwarantuje to, że nieprzetworzone zdarzenia będą kontynuować wędrówkę wzdłuż Responder Chain.

Często zadawane pytania

Czym jest Responder Chain w iOS?

Responder Chain to hierarchiczny łańcuch obiektów UIResponder, przez który iOS sekwencyjnie przekazuje zdarzenia dotyku, naciśnięć i gestów. Jeśli obiekt nie przetwarza zdarzenia, jest ono przekazywane do następnego obiektu responder w łańcuchu aż do UIApplication.

Jak zmienić kolejność łańcucha responderów?

Kolejność można zmienić, nadpisując właściwość next w swoim obiekcie UIResponder. Zwracając inny obiekt zamiast standardowego, przekierowujesz nieprzetworzone zdarzenia na niego. Jest to przydatne w niestandardowych hierarchiach, na przykład gdy niestandardowy kontener zarządza wieloma kontrolerami potomnymi.

Jaka jest różnica między hit-test a responder chain?

Hit-Testing określa, który widok znajduje się pod punktem dotyku (pierwotny odbiorca), a Responder Chain określa, jak zdarzenie jest przekazywane między obiektami po hit-teście. Hit-test znajduje pierwszy obiekt, responder chain zapewnia dalszą routing, jeśli ten obiekt nie przetwarza zdarzenia.

Jak przerwać łańcuch responderów?

Aby przerwać łańcuch, wystarczy przetworzyć zdarzenie w swoim UIResponder i nie wywoływać super. Na przykład nadpisując touchesBegan i nie wywołując super.touchesBegan, zapobiegasz przekazywaniu zdarzenia dalej. Zdarzenie zostanie przetworzone na bieżącym poziomie i nie dotrze do następnych ogniw łańcucha.

Dlaczego mój widok nie otrzymuje dotknięć?

Najczęstsze przyczyny: isUserInteractionEnabled ustawione na false, widok jest ukryty (isHidden = true), alpha mniejsze niż 0,01 lub widok znajduje się poza granicami rodzica. Sprawdź również, czy na widoku lub jego superview nie ma UIGestureRecognizer, który przechwytuje zdarzenia przed touchesBegan.

Podsumowanie

  • Responder Chain to fundamentalny mechanizm iOS do routingu zdarzeń wejściowych przez hierarchię UIResponder od first responder do UIApplication.
  • Hit-Testing poprzedza Responder Chain i określa, który widok otrzyma zdarzenie jako pierwszy, analizując hierarchię i współrzędne dotyku.
  • UIResponder udostępnia metody touchesBegan, touchesMoved, touchesEnded, touchesCancelled, pressesBegan i inne do obsługi różnych typów zdarzeń.
  • Wywołanie super w metodach obsługi zdarzeń określa, czy transmisja wzdłuż łańcucha będzie kontynuowana, czy zdarzenie zostanie przetworzone na bieżącym poziomie.
  • Komponenty UIKit (UITextField, UIButton, UITableView) aktywnie wykorzystują Responder Chain do standardowego działania, w tym klawiatury i menu kontekstowych.
  • Niestandardowy UIResponder umożliwia implementację specyficznej obsługi zdarzeń, nieprzewidzianej przez standardowe UIGestureRecognizer.
  • Prawidłowa konfiguracja next responder gwarantuje, że nieprzetworzone zdarzenia dotrą do odpowiedniego handlera w hierarchii aplikacji.

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.

Omów projekt

Przeczytaj również