Responder Chain is an iOS mechanism that sequentially passes touch, key press, and gesture events through the hierarchy of UIResponder objects until one of them handles the event. The chain starts with the object that detected the event and moves up the hierarchy: from the view to its superview, then to the view controller, window, and finally to UIApplication. According to Apple Developer Documentation (2026), this pattern allows separating event handling responsibility among interface components, providing flexibility without tight coupling to a specific handler.
Key Takeaways
Responder Chain is a sequence of UIResponder objects through which iOS passes input events such as touches, key presses, and accelerometer data. Each object in this chain has the ability to handle the event or pass it to the next responder object via the next property.
The mechanism is based on the view hierarchy: when a touch occurs, iOS first determines which view was touched (through hit-testing) and creates a chain starting from that view and going up to UIApplication. UIApplication is the last link in the chain — if an event reaches it and is not handled, it is simply discarded.
According to Apple, this pattern is critical for encapsulating event handling logic. A developer can override the behavior of a specific view without affecting other elements in the hierarchy. For example, UITextField becomes first responder when focused and receives keyboard events without requiring changes in the parent UIViewController.
Event handling through the Responder Chain happens in two stages: first, iOS determines which view received the event (hit-testing), then it runs the responder chain to handle it. If an object does not implement the corresponding method, the event is passed further.
The chain is formed dynamically based on the current first responder and the view hierarchy. The standard order is: first responder → its view → superview → UIViewController → root view → UIWindow → UIApplication. If any of these objects implements, for example, touchesBegan, the event is handled at that level and is not passed further.
import UIKit
class CustomView: UIView {
override func touchesBegan(
_ touches: Set<UITouch>,
with event: UIEvent?
) {
// Touch handled at this view level
print("CustomView handled touch")
// Forward event along the chain
super.touchesBegan(touches, with: event)
}
}
A key feature is that calling super.touchesBegan is not required. If you do not call it, the event will be handled only at the current level and will not go further along the Responder Chain. This gives the developer full control over which objects participate in handling.
When an object receives an event but does not handle it (does not override the method), iOS automatically passes the event to the next responder object via the next property. This property forms a singly linked list, which is called the Responder Chain.
UIViewController sits between its view and UIWindow: if the view does not handle the event, the controller gets a chance to do so. This is especially useful for common logic — for example, handling a gesture that should work across the entire scene, regardless of which view is under the user's finger.
Hit-Testing is the process by which iOS determines which view is under the touch point. The hitTest:withEvent: method traverses the view hierarchy from UIWindow downward, checking which child view contains the touch point and is not hidden.
The algorithm works recursively: for each level, iOS checks views in reverse order of addition (topmost first). If a view is not hidden, not transparent, and the point falls within its bounds, hitTest runs recursively for all its subviews. The deepest view satisfying all conditions becomes the hit-test view — the first object in the Responder Chain.
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
}
Developers can override hitTest to change the default behavior. For example, to extend the touch area for a small button or redirect the event to another view that is not physically under the finger. This is a powerful tool for creating custom interactive elements.
UIResponder is the base class for all objects that can handle events in iOS. UIView, UIViewController, UIApplication, and UIWindow inherit from UIResponder. The class provides a set of methods that can be overridden to handle different types of events.
The main method groups include touchesBegan, touchesMoved, touchesEnded, touchesCancelled for touches; pressesBegan, pressesEnded for physical buttons; and motionBegan, motionEnded for accelerometer events. Each method receives a set of UITouch or UIPress objects and a reference to UIEvent containing additional metadata about the event.
| UIResponder Method | Purpose |
|---|---|
| touchesBegan | Called when a touch begins |
| touchesMoved | Called when a finger moves |
| touchesEnded | Called when a finger is lifted |
| touchesCancelled | Called on interruption (call, control center swipe) |
| pressesBegan | Called when a physical button is pressed |
It is important to understand that iOS calls these methods only for the first responder and subsequent objects in the chain. If no object has overridden the method, the event does not generate an error — it is simply ignored. For debugging event handling, use a Symbolic Breakpoint on UIResponder touchEvent.
Standard UIKit components actively use the Responder Chain for their operation. UITextField becomes first responder when it receives focus, which automatically opens the keyboard. UIButton handles touches through the UIControl mechanism, which also relies on the responder chain.
UITableView and UICollectionView use the responder chain for handling cell selection and scroll gestures. If a user touches a cell, the event first reaches the cell itself, then UITableView, and only then UIViewController. UIGestureRecognizer has higher priority than touchesBegan — if a gesture recognizer is added to a view, it will receive the event first.
According to Apple, proper use of the Responder Chain is critical for app accessibility. VoiceOver and other assistive technologies use the responder chain for navigating between interface elements. If the chain is broken, users with disabilities will not be able to interact with the application.
UIMenuController for displaying context menus also uses the Responder Chain. When a user invokes the menu, the system looks for a first responder that implements the canPerformAction and corresponding action methods. The menu is displayed only for actions that the current responder supports.
This allows, for example, showing Cut, Copy, Paste commands only when UITextField is in focus, and hiding them when working with UILabel. A developer can add custom actions to the context menu by implementing them in a UIResponder subclass and returning true from canPerformAction.
Creating a custom responder object gives the developer full control over event handling. To do this, you need to create a subclass of UIResponder (or UIView/UIViewController) and override the necessary event handling methods.
Custom responder objects are often used for handling specific gestures that are not covered by standard UIGestureRecognizer. For example, recognizing shape drawing, complex multi-touch combinations, or proprietary input patterns. A custom responder can aggregate events from multiple fingers and make decisions based on their combination.
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)
}
}
}
When creating a custom responder, it is important to properly configure the next chain. If your object is not part of the standard UIKit hierarchy, you must explicitly specify which object will be its next responder. This ensures that unhandled events continue moving along the Responder Chain.
Frequently Asked Questions
Responder Chain is a hierarchical chain of UIResponder objects through which iOS sequentially passes touch, press, and gesture events. If an object does not handle the event, it is passed to the next responder object along the chain up to UIApplication.
You can change the order by overriding the next property of your UIResponder object. By returning a different object instead of the default one, you redirect unhandled events to it. This is useful for non-standard hierarchies, for example, when a custom container manages multiple child controllers.
Hit-Testing determines which view is under the touch point (the initial recipient), while Responder Chain determines how the event is passed between objects after hit-test. Hit-test finds the first object, the responder chain provides further routing if that object does not handle the event.
To break the chain, simply handle the event in your UIResponder and do not call super. For example, by overriding touchesBegan and not calling super.touchesBegan, you prevent the event from being passed further. The event will be handled at the current level and will not reach the next links in the chain.
The most common reasons: isUserInteractionEnabled is set to false, the view is hidden (isHidden = true), alpha is less than 0.01, or the view is outside the bounds of the parent container. Also check that there is no UIGestureRecognizer on the view or its superview that intercepts events before touchesBegan.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also