響應(yīng)者鏈條
事件的響應(yīng)
用戶點(diǎn)擊屏幕產(chǎn)生的一個觸摸事件,經(jīng)過一系列的傳遞過程后,會找到一個最適合的視圖來處理事件.找到最合適的視圖控件后,就會調(diào)用控件的touches方法來作具體的時間處理.touches的默認(rèn)做法是將事件順著響應(yīng)者鏈條向上傳遞,將事件交給上一個響應(yīng)者處理
- 什么是響應(yīng)者鏈條?
由多個響應(yīng)者對象連接起來的鏈條
- 什么是響應(yīng)者對象?
繼承了UIResponder的對象
- 系統(tǒng)是如何尋找最合適的View
1.先判斷自己是否能接收觸摸事件
2.再判斷觸摸的當(dāng)前點(diǎn)在不在自己身上
3.如果在自己身上,它會從后往前遍歷子控件,遍歷出每一個控件后,重啟前兩步
4.如果沒有符合條件的子控件,那么自身就是最合適的View
在尋找最合適View的過程中,系統(tǒng)會調(diào)用2個方法
- hitTest
- pointInside
在開發(fā)中或多或少會需要一些特殊的點(diǎn)擊,例如:
一個按鈕被一個半透明的View部分遮擋,需要點(diǎn)擊到按鈕的時候,按鈕始終響應(yīng)
一個View超出了父視圖的范圍,需要點(diǎn)擊超出范圍的View也有響應(yīng)
當(dāng)一個控件不能接收時間時一般有以下幾種情況
1.不接收用戶交互userInteractionEnabled = NO
2.當(dāng)一個控件隱藏時Hidden = YES
3.當(dāng)一個控件為透明白時
4.觸摸時間的傳遞是從父控件傳遞到子控件的,如果一個父控件不能接收事件,那么他里面的子控件也不能接收.
一次完整的觸摸事件的傳遞響應(yīng)的過程
- UIAppliction --> UIWiondw -->遞歸找到最適合處理事件的控件-->控件調(diào)用touches方法-->判斷是否實(shí)現(xiàn)touches方法-->沒有實(shí)現(xiàn)默認(rèn)會將事件傳遞給上一個響應(yīng)者-->找到上一個響應(yīng)者
代碼演示之按鈕被一個半透明的View部分遮擋,需要點(diǎn)擊到按鈕的時候,按鈕始終響應(yīng)
- 效果

響應(yīng)者鏈條測試.gif
- storyBoard處理

storyBoard
- ViewController
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func clickButton(sender: AnyObject) {
print("按鈕被點(diǎn)擊了")
}
}
- WHTestView(即半透明view)代碼
import UIKit
class WHTestView: UIView {
@IBOutlet weak var button: UIButton!
override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
let BtnPiont = convertPoint(point, toView: button)
if button.pointInside(BtnPiont, withEvent: event){
return false
}
return super.pointInside(point, withEvent: event)
}
}
- 注意:WHTestView中的button要反向拖線