Responder Chain: что это, принцип работы и цепочка ответчиков

Автор: IT Sectr Опубликовано: 2026-07-09 Время чтения: 9 мин

Responder Chain — это механизм iOS, который последовательно передаёт события касания, нажатия клавиш и жестов через иерархию объектов UIResponder, пока один из них не обработает событие. Цепочка начинается с объекта, обнаружившего событие, и движется вверх по иерархии: от view к её superview, затем к view controller, window и, наконец, к UIApplication. По данным Apple Developer Documentation (2026), этот паттерн позволяет разделить ответственность за обработку событий между компонентами интерфейса, обеспечивая гибкость без жёсткой привязки к конкретному обработчику.

Главное

  • Responder Chain — иерархическая цепочка объектов UIResponder для последовательной передачи событий от первого ответчика до UIApplication.
  • Hit-Testing определяет, какой объект станет первым в цепочке ответчиков, анализируя вложенность view в точке касания.
  • Каждый UIResponder может обработать событие или передать его дальше по цепочке через метод next.
  • UIApplication — конечный узел цепочки: если ни один объект не обработал событие, оно отбрасывается.
  • Кастомные обработчики создаются переопределением методов touchesBegan, touchesMoved, touchesEnded в подклассах UIView или UIViewController.

Что такое Responder Chain

Responder Chain — это последовательность объектов UIResponder, через которые iOS передаёт события ввода, такие как касания, нажатия клавиш и акселерометр. Каждый объект в этой цепочке имеет возможность обработать событие или передать его следующему responder-объекту через свойство next.

Механизм основан на иерархии view: когда происходит касание, iOS сначала определяет, какая view была нажата (через hit-testing), и создаёт цепочку, начиная с этой view и поднимаясь до UIApplication. UIApplication является последним звеном цепочки — если событие доходит до него и не обрабатывается, оно просто отбрасывается.

По данным Apple, этот паттерн критически важен для инкапсуляции логики обработки событий. Разработчик может переопределить поведение конкретной view, не затрагивая остальные элементы иерархии. Например, UITextField становится first responder при фокусе и получает события клавиатуры, не требуя изменений в родительском UIViewController.

Как Responder Chain обрабатывает события

Обработка событий через Responder Chain происходит в два этапа: сначала iOS определяет, какая view получила событие (hit-testing), затем запускает цепочку ответчиков для его обработки. Если объект не реализует соответствующий метод, событие передаётся дальше.

Цепочка формируется динамически на основе текущего first responder и иерархии view. Стандартный порядок выглядит так: first responder → его view → superview → UIViewController → root view → UIWindow → UIApplication. Если любой из этих объектов реализует, например, touchesBegan, событие обрабатывается на этом уровне и не передаётся дальше.

swift
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)
    }
}

Ключевая особенность — вызов super.touchesBegan не является обязательным. Если его не вызвать, событие будет обработано только на текущем уровне и не пойдёт дальше по Responder Chain. Это даёт разработчику полный контроль над тем, какие объекты участвуют в обработке.

Передача событий между responder-объектами

Когда объект получает событие, но не обрабатывает его (не переопределяет метод), iOS автоматически передаёт событие следующему responder-объекту через свойство next. Это свойство формирует односвязный список, который и называется Responder Chain.

UIViewController находится между своей view и UIWindow: если view не обрабатывает событие, контроллер получает шанс это сделать. Это особенно полезно для общей логики — например, обработки жеста, который должен работать на всей сцене, независимо от того, какая view под пальцем пользователя.

Hit-Testing: от касания до первого ответчика

Hit-Testing — это процесс, с помощью которого iOS определяет, какая view находится под точкой касания. Метод hitTest:withEvent: обходит иерархию view от UIWindow вниз, проверяя, какая из дочерних view содержит точку касания и не скрыта.

Алгоритм работает рекурсивно: для каждого уровня iOS проверяет view в обратном порядке добавления (сначала верхние). Если view не скрыта, не прозрачна и точка попадает в её bounds, для неё запускается hitTest рекурсивно для всех subviews. Самая глубокая view, удовлетворяющая всем условиям, становится hit-test view — первым объектом в 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
}

Разработчики могут переопределить hitTest, чтобы изменить стандартное поведение. Например, расширить область касания для маленькой кнопки или перенаправить событие на другую view, которая физически не находится под пальцем. Это мощный инструмент для создания кастомных интерактивных элементов.

Методы UIResponder для цепочки ответчиков

UIResponder — базовый класс для всех объектов, которые могут обрабатывать события в iOS. UIView, UIViewController, UIApplication и UIWindow наследуются от UIResponder. Класс предоставляет набор методов, которые можно переопределить для обработки различных типов событий.

Основные группы методов включают touchesBegan, touchesMoved, touchesEnded, touchesCancelled для касаний; pressesBegan, pressesEnded для физических кнопок; и motionBegan, motionEnded для событий акселерометра. Каждый метод получает набор объектов UITouch или UIPress и ссылку на UIEvent, содержащий дополнительные метаданные о событии.

Метод UIResponderНазначение
touchesBeganВызывается при начале касания
touchesMovedВызывается при перемещении пальца
touchesEndedВызывается при отпускании пальца
touchesCancelledВызывается при прерывании (звонок, свайп шторки)
pressesBeganВызывается при нажатии физической кнопки

Важно понимать, что iOS вызывает эти методы только для first responder и последующих объектов в цепочке. Если ни один объект не переопределил метод, событие не генерирует ошибку — оно просто игнорируется. Для отладки обработки событий используйте Symbolic Breakpoint на UIResponder touchEvent.

Responder Chain и UIKit элементы

Стандартные UIKit компоненты активно используют Responder Chain для своей работы. UITextField становится first responder при получении фокуса, что автоматически открывает клавиатуру. UIButton обрабатывает касания через UIControl механизм, который также опирается на responder chain.

UITableView и UICollectionView используют цепочку ответчиков для обработки выделения ячеек и жестов прокрутки. Если пользователь касается ячейки, событие сначала получает сама ячейка, затем UITableView, и только потом UIViewController. UIGestureRecognizer имеет более высокий приоритет, чем touchesBegan — если на view добавлен распознаватель жестов, он получит событие первым.

По данным Apple, правильное использование Responder Chain критически важно для доступности приложения. VoiceOver и другие ассистивные технологии используют цепочку ответчиков для навигации между элементами интерфейса. Если цепочка разорвана, пользователи с ограниченными возможностями не смогут взаимодействовать с приложением.

UIMenuController и Responder Chain

UIMenuController для отображения контекстного меню также использует Responder Chain. Когда пользователь вызывает меню, система ищет first responder, который реализует методы canPerformAction и соответствующие action-методы. Меню отображается только для тех действий, которые поддерживает текущий responder.

Это позволяет, например, показать команды Cut, Copy, Paste только когда UITextField в фокусе, и скрыть их при работе с UILabel. Разработчик может добавить кастомные действия в контекстное меню, реализовав их в подклассе UIResponder и вернув true из canPerformAction.

Кастомные responder объекты в iOS

Создание кастомного responder объекта даёт разработчику полный контроль над обработкой событий. Для этого нужно создать подкласс UIResponder (или UIView/UIViewController) и переопределить необходимые методы обработки событий.

Часто кастомные responder объекты используются для обработки специфических жестов, которые не покрываются стандартными UIGestureRecognizer. Например, распознавание рисования фигур, сложных multi-touch комбинаций или проприетарных паттернов ввода. Кастомный responder может агрегировать события от нескольких пальцев и принимать решение на основе их комбинации.

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)
        }
    }
}

При создании кастомного responder важно правильно настроить цепочку next. Если ваш объект не является частью стандартной иерархии UIKit, необходимо явно указать, какой объект будет его next responder. Это гарантирует, что необработанные события продолжат движение по Responder Chain.

Часто задаваемые вопросы

Что такое Responder Chain в iOS?

Responder Chain — это иерархическая цепочка объектов UIResponder, через которую iOS последовательно передаёт события касания, нажатий и жестов. Если объект не обрабатывает событие, оно передаётся следующему responder-объекту по цепочке до UIApplication.

Как изменить порядок цепочки ответчиков?

Изменить порядок можно, переопределив свойство next у вашего UIResponder объекта. Вернув другой объект вместо стандартного, вы перенаправляете необработанные события на него. Это полезно для нестандартных иерархий, например, когда кастомный контейнер управляет несколькими дочерними контроллерами.

В чем разница между hit-test и responder chain?

Hit-Testing определяет, какая view находится под точкой касания (исходный получатель), а Responder Chain определяет, как событие передаётся между объектами после hit-test. Hit-test находит первый объект, responder chain обеспечивает дальнейшую маршрутизацию, если этот объект не обрабатывает событие.

Как прервать цепочку ответчиков?

Чтобы прервать цепочку, достаточно обработать событие в вашем UIResponder и не вызывать super. Например, переопределив touchesBegan и не вызывая super.touchesBegan, вы предотвращаете передачу события дальше. Событие будет обработано на текущем уровне и не достигнет следующих звеньев цепочки.

Почему моя view не получает касания?

Наиболее частые причины: isUserInteractionEnabled установлен в false, view скрыта (isHidden = true), alpha меньше 0.01, или view находится за пределами bounds родительского контейнера. Также проверьте, что на view или её superview нет UIGestureRecognizer, который перехватывает события до touchesBegan.

Итоги

  • Responder Chain — фундаментальный механизм iOS для маршрутизации событий ввода через иерархию UIResponder от first responder до UIApplication.
  • Hit-Testing предшествует Responder Chain и определяет, какая view получит событие первой, анализируя иерархию и координаты касания.
  • UIResponder предоставляет методы touchesBegan, touchesMoved, touchesEnded, touchesCancelled, pressesBegan и другие для обработки различных типов событий.
  • Вызов super в методах обработки событий определяет, продолжится ли передача по цепочке или событие будет обработано на текущем уровне.
  • UIKit компоненты (UITextField, UIButton, UITableView) активно используют Responder Chain для стандартного поведения, включая клавиатуру и контекстные меню.
  • Кастомный UIResponder позволяет реализовать специфическую обработку событий, не предусмотренную стандартными UIGestureRecognizer.
  • Правильная настройка next responder гарантирует, что необработанные события дойдут до нужного обработчика в иерархии приложения.

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также