iOS 事件傳遞和響應(yīng)者鏈條

事件的傳遞

  • 發(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;
    }
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容