事件的傳遞
- 發(fā)生觸摸事件后,系統(tǒng)會(huì)將該事件加入到一個(gè)由UIApplication管理的事件隊(duì)列中。
- UIApplication會(huì)從事件隊(duì)列中取出最前面的事件,并將事件分發(fā)下去以便處理,通常,先發(fā)送事件給應(yīng)用程序的主窗口(keywWndow)。
- 主窗口會(huì)在視圖層次結(jié)構(gòu)中找到一個(gè)最合適的視圖來處理觸摸事件,這也是整個(gè)事件處理過程的第一步。
- 找到合適的視圖控制控件后,就會(huì)調(diào)用視圖控件的touches方法來做具體的事件處理。
- 觸摸事件的傳遞是從父控件傳到子控件UIApplication –>UIWindow ->父控件->子控件
- 注意點(diǎn):如果父控件不能接收觸摸事件,那么自控件就不可能接收到觸摸事件UIView不接收觸摸事件的三種情況
- 不接收用戶交互
- self.view.userInteractionEnabled = NO;
- 隱藏
- self.view.hidden = YES;
- 透明
- self.view.alpha = 0;
// point:是方法調(diào)用者坐標(biāo)系上的觸摸點(diǎn)的位置 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { // 1.判斷下能否接收觸摸事件 if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.0) return nil; // 2.判斷下點(diǎn)在不在控件上 if ([self pointInside:point withEvent:event] == NO) return nil; // 3.從后往前遍歷子控件 int count = (int)self.subviews.count; for (int i = count - 1; i >= 0 ; i--) { // 取出顯示在最前面的子控件 UIView *childView = self.subviews[i]; // 轉(zhuǎn)換成子控件坐標(biāo)系上點(diǎn) CGPoint childP = [self convertPoint:point toView:childView]; UIView *fitView = [childView hitTest:childP withEvent:event]; if (fitView) { return fitView; } } // 表示沒有比自己更合適的view return self; }
如何找到最合適的view
- 自己是否能接收觸摸事件
- 觸摸點(diǎn)是否在自己的身上
- 從后往前遍歷子控件,重復(fù)前面的兩個(gè)步驟
- 如果沒有符合條件的子控件,那么就自己最適合處理
響應(yīng)者鏈條
- 定義:是由多個(gè)響應(yīng)者對(duì)象連接起來的鏈條。
- 作用:能很清楚的看見每個(gè)響應(yīng)者之間的聯(lián)系,并且可以讓一個(gè)事件多個(gè)對(duì)象處理。
- 響應(yīng)者對(duì)象:能處理事件的對(duì)象。
- 默認(rèn)做法是將事件順著響應(yīng)者鏈條向上傳遞,將事件交給上一個(gè)響應(yīng)者進(jìn)行處理。
- 如何判斷上一個(gè)響應(yīng)者
- 如果當(dāng)前這個(gè)view是控制器的view,那么控制器就是上一個(gè)響應(yīng)者。
- 如果當(dāng)前這個(gè)view不是控制器的view,那么父控件就是上一個(gè)響應(yīng)者。
//尋找合適的view //什么時(shí)候調(diào)用,只要一個(gè)事件傳遞給一個(gè)控件,就會(huì)調(diào)用這個(gè)控件的hitTest,返回誰,誰就是最合適的view //point:表示方法調(diào)用者坐標(biāo)系上的點(diǎn)。 - (UIView* )hitTest:(CGPoint)point withEvent:(UIEvent *)event{ return self; } //判斷下當(dāng)前這個(gè)點(diǎn)在不在方法調(diào)用者上 //使用注意點(diǎn):點(diǎn)必須是方法調(diào)用者上的坐標(biāo)系,才會(huì)判斷準(zhǔn)確 -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{ //返回YES事件才會(huì)往子控件傳遞, return YES; }