Responder Chain, iOS'ta dokunma, tuş basma ve jest olaylarını UIResponder nesneleri hiyerarşisi aracılığıyla sırayla ileten ve bunlardan biri olayı işleyene kadar devam eden bir mekanizmadır. Zincir, olayı algılayan nesneyle başlar ve hiyerarşide yukarı doğru hareket eder: view'den superview'ine, ardından view controller'a, window'a ve son olarak UIApplication'a. Apple Developer Documentation (2026)'ya göre, bu desen, olay işleme sorumluluğunu arayüz bileşenleri arasında ayırmaya olanak tanır ve belirli bir işleyiciye katı bağlantı olmadan esneklik sağlar.
Önemli Noktalar
Responder Chain, iOS'un dokunma, tuş basımı ve ivmeölçer verileri gibi giriş olaylarını ilettiği bir UIResponder nesneleri dizisidir. Bu zincirdeki her nesne, olayı işleme veya next özelliği aracılığıyla bir sonraki yanıtlayıcı nesneye iletme yeteneğine sahiptir.
Mekanizma, view hiyerarşisine dayanır: bir dokunma meydana geldiğinde, iOS önce hangi view'ın dokunulduğunu belirler (hit-testing yoluyla) ve bu view'dan başlayarak UIApplication'a kadar bir zincir oluşturur. UIApplication zincirin son halkasıdır — bir olay ona ulaşır ve işlenmezse, basitçe atılır.
Apple'a göre, bu desen olay işleme mantığını kapsülleme için kritiktir. Bir geliştirici, hiyerarşideki diğer öğeleri etkilemeden belirli bir view'ın davranışını geçersiz kılabilir. Örneğin, UITextField odak aldığında ilk yanıtlayıcı olur ve üst UIViewController'da değişiklik gerektirmeden klavye olaylarını alır.
Olay işleme, Responder Chain aracılığıyla iki aşamada gerçekleşir: önce iOS hangi view'ın olayı aldığını belirler (hit-testing), ardından işlemek için yanıtlayıcı zincirini çalıştırır. Bir nesne ilgili yöntemi uygulamazsa, olay daha ileri iletilir.
Zincir, mevcut ilk yanıtlayıcıya ve view hiyerarşisine bağlı olarak dinamik olarak oluşur. Standart sıra şöyledir: ilk yanıtlayıcı → view'ı → superview → UIViewController → kök view → UIWindow → UIApplication. Bu nesnelerden herhangi biri örneğin touchesBegan'ı uygularsa, olay o seviyede işlenir ve daha ileri iletilmez.
import UIKit
class CustomView: UIView {
override func touchesBegan(
_ touches: Set<UITouch>,
with event: UIEvent?
) {
// Dokunma bu view seviyesinde işlendi
print("CustomView dokunmayı işledi")
// Olayı zincir boyunca ilet
super.touchesBegan(touches, with: event)
}
}
Önemli bir özellik, super.touchesBegan çağrısının zorunlu olmamasıdır. Çağrılmazsa, olay yalnızca geçerli seviyede işlenir ve Responder Chain boyunca devam etmez. Bu, geliştiriciye hangi nesnelerin işlemeye katılacağı konusunda tam kontrol sağlar.
Bir nesne bir olay alır ancak işlemezse (yöntemi geçersiz kılmazsa), iOS otomatik olarak next özelliği aracılığıyla olayı bir sonraki yanıtlayıcı nesneye iletir. Bu özellik, Responder Chain olarak adlandırılan tek yönlü bağlı bir liste oluşturur.
UIViewController, view'ı ile UIWindow arasında bulunur: view olayı işlemezse, denetleyici bunu yapma şansına sahip olur. Bu, özellikle ortak mantık için kullanışlıdır — örneğin, kullanıcının parmağının altındaki view'dan bağımsız olarak tüm sahnede çalışması gereken bir jesti işlemek.
Hit-Testing, iOS'un dokunma noktasının altında hangi view'ın bulunduğunu belirleme sürecidir. hitTest:withEvent: yöntemi, UIWindow'den aşağıya doğru view hiyerarşisini dolaşarak hangi alt view'ın dokunma noktasını içerdiğini ve gizli olmadığını kontrol eder.
Algoritma yinelemeli olarak çalışır: her seviye için iOS, view'ları ekleme sırasının tersine göre kontrol eder (önce en üstteki). Bir view gizli değilse, şeffaf değilse ve nokta sınırları içindeyse, tüm alt view'ları için yinelemeli olarak hitTest çalıştırılır. Tüm koşulları karşılayan en derin view, hit-test view haline gelir — Responder Chain'deki ilk nesne.
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
}
Geliştiriciler, varsayılan davranışı değiştirmek için hitTest'i geçersiz kılabilir. Örneğin, küçük bir düğmenin dokunma alanını genişletmek veya olayı fiziksel olarak parmağın altında olmayan başka bir view'a yönlendirmek için. Bu, özel etkileşimli öğeler oluşturmak için güçlü bir araçtır.
UIResponder, iOS'ta olayları işleyebilen tüm nesneler için temel sınıftır. UIView, UIViewController, UIApplication ve UIWindow, UIResponder'dan miras alır. Sınıf, farklı türdeki olayları işlemek için geçersiz kılınabilen bir dizi yöntem sağlar.
Ana yöntem grupları, dokunmalar için touchesBegan, touchesMoved, touchesEnded, touchesCancelled; fiziksel düğmeler için pressesBegan, pressesEnded; ve ivmeölçer olayları için motionBegan, motionEnded içerir. Her yöntem bir dizi UITouch veya UIPress nesnesi ve olay hakkında ek meta veriler içeren UIEvent'e bir referans alır.
| UIResponder Yöntemi | Amaç |
|---|---|
| touchesBegan | Dokunma başladığında çağrılır |
| touchesMoved | Parmak hareket ettiğinde çağrılır |
| touchesEnded | Parmak kaldırıldığında çağrılır |
| touchesCancelled | Kesinti durumunda çağrılır (arama, kontrol merkezi kaydırma) |
| pressesBegan | Fiziksel düğmeye basıldığında çağrılır |
iOS'un bu yöntemleri yalnızca ilk yanıtlayıcı ve zincirdeki sonraki nesneler için çağırdığını anlamak önemlidir. Hiçbir nesne yöntemi geçersiz kılmadıysa, olay bir hata oluşturmaz — basitçe yok sayılır. Olay işlemeyi hata ayıklamak için UIResponder touchEvent üzerinde Sembolik Kesme Noktası kullanın.
Standart UIKit bileşenleri, çalışmaları için Responder Chain'i aktif olarak kullanır. UITextField, odak aldığında ilk yanıtlayıcı olur ve otomatik olarak klavyeyi açar. UIButton, UIControl mekanizması aracılığıyla dokunmaları işler ve bu da yanıtlayıcı zincirine dayanır.
UITableView ve UICollectionView, hücre seçimini ve kaydırma jestlerini işlemek için yanıtlayıcı zincirini kullanır. Bir kullanıcı bir hücreye dokunursa, olay önce hücrenin kendisine, ardından UITableView'ye ve ancak ondan sonra UIViewController'a ulaşır. UIGestureRecognizer, touchesBegan'dan daha yüksek önceliğe sahiptir — bir view'a jest tanıyıcı eklenirse, olayı ilk o alır.
Apple'a göre, Responder Chain'in doğru kullanımı uygulama erişilebilirliği için kritiktir. VoiceOver ve diğer yardımcı teknolojiler, arayüz öğeleri arasında gezinmek için yanıtlayıcı zincirini kullanır. Zincir kırılırsa, engelli kullanıcılar uygulamayla etkileşime giremez.
UIMenuController, bağlam menülerini görüntülemek için de Responder Chain'i kullanır. Bir kullanıcı menüyü çağırdığında, sistem canPerformAction ve ilgili eylem yöntemlerini uygulayan bir ilk yanıtlayıcı arar. Menü, yalnızca geçerli yanıtlayıcının desteklediği eylemler için görüntülenir.
Bu, örneğin, Kes, Kopyala, Yapıştır komutlarını yalnızca UITextField odaktayken göstermeye ve UILabel ile çalışırken gizlemeye olanak tanır. Bir geliştirici, bunları UIResponder alt sınıfında uygulayarak ve canPerformAction'dan true döndürerek bağlam menüsüne özel eylemler ekleyebilir.
Özel bir yanıtlayıcı nesnesi oluşturmak, geliştiriciye olay işleme üzerinde tam kontrol sağlar. Bunu yapmak için, UIResponder (veya UIView/UIViewController) alt sınıfı oluşturmanız ve gerekli olay işleme yöntemlerini geçersiz kılmanız gerekir.
Özel yanıtlayıcı nesneleri genellikle standart UIGestureRecognizer tarafından kapsanmayan belirli jestleri işlemek için kullanılır. Örneğin, şekil çizme tanıma, karmaşık çoklu dokunma kombinasyonları veya tescilli giriş desenleri. Özel bir yanıtlayıcı, birden çok parmaktan gelen olayları toplayabilir ve bunların kombinasyonuna göre kararlar alabilir.
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)
}
}
}
Özel bir yanıtlayıcı oluştururken, next zincirini doğru şekilde yapılandırmak önemlidir. Nesneniz standart UIKit hiyerarşisinin bir parçası değilse, hangi nesnenin onun next yanıtlayıcısı olacağını açıkça belirtmelisiniz. Bu, işlenmemiş olayların Responder Chain boyunca hareket etmeye devam etmesini sağlar.
Sıkça Sorulan Sorular
Responder Chain, iOS'un dokunma, basma ve jest olaylarını sırayla ilettiği UIResponder nesnelerinin hiyerarşik bir zinciridir. Bir nesne olayı işlemezse, zincirdeki bir sonraki yanıtlayıcı nesneye UIApplication'a kadar iletilir.
UIResponder nesnenizin next özelliğini geçersiz kılarak sırayı değiştirebilirsiniz. Varsayılan yerine farklı bir nesne döndürerek, işlenmemiş olayları ona yönlendirirsiniz. Bu, standart olmayan hiyerarşiler için kullanışlıdır, örneğin özel bir kapsayıcının birden çok alt denetleyiciyi yönettiği durumlarda.
Hit-Testing dokunma noktasının altındaki view'ı (ilk alıcı) belirlerken, Responder Chain hit-test'ten sonra olayın nesneler arasında nasıl iletileceğini belirler. Hit-test ilk nesneyi bulur, bu nesne olayı işlemezse yanıtlayıcı zinciri ilave yönlendirme sağlar.
Zinciri kesmek için, UIResponder'ınızda olayı işleyin ve super'i çağırmayın. Örneğin, touchesBegan'ı geçersiz kılıp super.touchesBegan'ı çağırmayarak, olayın daha ileri iletilmesini engellersiniz. Olay geçerli seviyede işlenir ve zincirin sonraki halkalarına ulaşmaz.
En yaygın nedenler: isUserInteractionEnabled false olarak ayarlanmış, view gizli (isHidden = true), alpha 0,01'den küçük veya view üst kapsayıcının sınırlarının dışında. Ayrıca view'da veya superview'inde touchesBegan'dan önce olayları engelleyen bir UIGestureRecognizer olup olmadığını kontrol edin.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun