Responder Chain је iOS механизам који секвенцијално преноси догађаје додира, притиска тастера и покрета кроз хијерархију UIResponder објеката, док један од њих не обради догађај. Ланац почиње од објекта који је открио догађај и креће се нагоре кроз хијерархију: од view-а до његовог superview-а, затим до view controller-а, window-а и, на крају, до UIApplication-а. Према Apple Developer Documentation (2026), овај образац омогућава поделу одговорности за обраду догађаја између компонената интерфејса, пружајући флексибилност без чврсте везе за одређени хандлер.
Главно
Responder Chain је секвенца UIResponder објеката кроз коју iOS преноси улазне догађаје, као што су додири, притисци тастера и акселерометар. Сваки објекат у овом ланцу има могућност да обради догађај или га проследи следећем UIResponder објекту путем својства next.
Механизам се заснива на хијерархији view-ова: када дође до додира, iOS прво одређује који view је притиснут ( путем hit-testing-а) и ствара ланац који почиње од тог view-а и иде нагоре до UIApplication-а. UIApplication је последња карика ланца — ако догађај стигне до њега и није обрађен, једноставно се одбацује.
Према Apple-у, овај образац је клучан за капсулацију логике обраде догађаја. Програмер може да прегаци понашање одређеног view-а без утицаја на остале елементе хијерархије. На пример, UITextField постаје first responder при добијању фокуса и прима догађаје тастатуре без потребе за променама у родитељском UIViewController-у.
Обрада догађаја кроз Responder Chain одвија се у два корака: прво iOS одређује који view је примио догађај (hit-testing), затим покреће ланац одговарача за његову обраду. Ако објекат не имплементира одговарајућу методу, догађај се прослеђује даље.
Ланац се формира динамички на основу тренутног first responder-а и хијерархије view-ова. Стандардни редослед је: first responder → његов view → superview → UIViewController → root view → UIWindow → UIApplication. Ако било који од ових објеката имплементира, на пример, touchesBegan, догађај се обрађује на том нивоу и не прослеђује се даље.
import UIKit
class CustomView: UIView {
override func touchesBegan(
_ touches: Set<UITouch>,
with event: UIEvent?
) {
// Додир обрађен на овом нивоу view-а
print("CustomView је обрадио додир")
// Проследи догађај даље кроз ланац
super.touchesBegan(touches, with: event)
}
}
Кључна карактеристика је да позив super.touchesBegan није обавезан. Ако се не позове, догађај ће бити обрађен само на тренутном нивоу и неће наставити кроз Responder Chain. Ово пружа програмеру потпуну контролу над тиме који објекти учествују у обради.
Када објекат прими догађај, али га не обрађује (не прегацује методу), iOS аутоматски прослеђује догађај следећем responder објекту путем својства next. Ово својство формира једносмерну листу која се назива Responder Chain.
UIViewController се налази између својог view-а и UIWindow-а: ако view не обрађује догађај, контролер има прилику да то уради. Ово је посебно корисно за заједничку логику — на пример, обраду покрета који би требало да ради на целој сцени, без обзира на то који се view налази испод прста корисника.
Hit-Testing је процес којим iOS одређује који се view налази испод тачке додира. Метода hitTest:withEvent: обилази хијерархију view-ова од UIWindow-а надоле, проверавајући који од потомака садржи тачку додира и није сакривен.
Алгоритам ради рекурзивно: за сваки ниво, iOS проверава view-ове обрнутим редоследом додавања (прво горње). Ако view није сакривен, није прозиран и тачка се налази у његовом bounds-у, hitTest се покреће рекурзивно за све subview-ове. Најдубљи view који испуњава све услове постаје hit-test view — први објекат у 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
}
Програмери могу да прегаце hitTest да би променили стандардно понашање. На пример, да прошире подручје додира за мали дугме или да преусмери догађај на други view који се физички не налази испод прста. Ово је моћан алат за креирање прилагођених интерактивних елемената.
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-у.
Стандардни UIKit компоненти активно користе Responder Chain за свој рад. UITextField постаје first responder при добијању фокуса, што аутоматски отвара тастатуру. UIButton обрађује додире кроз UIControl механизам, који такође зависи од responder chain-а.
UITableView и UICollectionView користе ланац одговарача за обраду селекције ћелија и покрета за помицање. Ако корисник додирне ћелију, догађај прво прима сама ћелија, затим UITableView, и тек онда UIViewController. UIGestureRecognizer има виши приоритет од touchesBegan-а — ако је на view додат препознавач покрета, он ће први примити догађај.
Према Apple-у, правилна употреба Responder Chain-а је кључна за приступачност апликације. VoiceOver и друге помоћне технологије користе ланац одговарача за навигацију између елемената интерфејса. Ако је ланац прекинут, корисници са потешкоћама неће моћи да интерагују са апликацијом.
UIMenuController за приказ контекстног менија такође користи Responder Chain. Када корисник позове мени, систем тражи first responder који имплементира методе canPerformAction и одговарајуће акционе методе. Мени се приказује само за оне радње које тренутни responder подржава.
Ово омогућава, на пример, приказ команди Изрежи, Копирај, Налепи само када је UITextField у фокусу, и њихово сакривање при раду са UILabel-ом. Програмер може да дода прилагођене радње у контекстни мени, имплементирајући их у подкласи UIResponder-а и враћајући true из canPerformAction-а.
Креирање прилагођеног responder објекта пружа програмеру потпуну контролу над обрадом догађаја. За ово је потребно креирати подкласу UIResponder-а (или UIView/UIViewController) и прегацати потребне методе обраде догађаја.
Често се прилагођени responder објекти користе за обраду специфичних покрета који нису покривени стандардним UIGestureRecognizer-ом. На пример, препознавање цртања облика, сложених multi-touch комбинација или проприетарних образаца уноса. Прилагођени responder може да агрегира догађаје са више прстију и донесе одлуку на основу њихове комбинације.
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)
}
}
}
При креирању прилагођеног respondera важно је правилно поставити next ланац. Ако ваш објекат није део стандардне UIKit хијерархије, морате експлицитно навести који ће објекат бити његов next responder. Ово гарантује да ће необрађени догађаји наставити своје кретање кроз Responder Chain.
Често постављана питања
Responder Chain је хијерархијски ланац UIResponder објеката кроз који iOS секвенцијално преноси догађаје додира, притиска и покрета. Ако објекат не обради догађај, он се прослеђује следећем responder објекту у ланцу све до UIApplication-а.
Редослед се може променити прегацањем својства next код вашег UIResponder објекта. Враћањем другог објекта уместо стандардног, преусмеравате необрађене догађаје на њега. Ово је корисно за нестандардне хијерархије, на пример, када прилагођени контејнер управља више потомака.
Hit-Testing одређује који се view налази испод тачке додира (првобитни прималац), а Responder Chain одређује како се догађај преноси између објеката након hit-test-а. Hit-test проналази први објекат, а responder chain обезбеђује даље усмеравање ако тај објекат не обради догађај.
Да бисте прекинули ланац, довољно је да обрадите догађај у вашем UIResponder-у и не позовете super. На пример, прегацањем touchesBegan-а и непозивањем super.touchesBegan-а, спречавате преношење догађаја даље. Догађај ће бити обрађен на тренутном нивоу и неће доспети до следећих карика ланца.
Најчешћи узроци: isUserInteractionEnabled је постављен на false, view је сакривен (isHidden = true), alpha је мањи од 0,01 или се view налази изван граница родитељског контејнера. Такође проверите да ли на view-у или његовом superview-у постоји UIGestureRecognizer који пресреће догађаје пре него што их прими touchesBegan.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође