iOSUI-事件處理

事件的產生以及傳遞
事件是怎麼樣產生與傳遞的?
      1.當發生一個觸摸事件後,系統會將該事件加入到一個由UIApplication管理的事件隊列中.
      2.UIApplication會從事件隊列中取出最前面的事件,交給主窗口window. 
      3.主窗口會在視圖層次結構中找到一個最合適的視圖來處理觸摸事件
      觸摸事件的傳遞是從父控件傳遞到子控件的.
      若是一個父控件不能接收事件,那麼它裏面的子控件也不可以接收事件.
一個控件什麼狀況下不可以接收事件?
      1.不接收用戶交互時不可以處理事件
         userInteractionEnabled = NO
      2.當一個控件隱藏的時候不可以接收事件
          Hidden = YES的時候
      3.當一個控件爲透明的時候也不可以接收事件
          注意:UIImageView的userInteractionEnabled默認就是NO,
          所以UIImageView以及它的子控件默認是不能接收觸摸事件的
如何尋找最合適的View?
1.先判斷本身是否可以接收觸摸事件,若是能再繼續往下判斷,
2.再判斷觸摸的當前點在不在本身的身上.
3.若是在本身身上,它會從後往前遍歷子控件,遍歷出每個子控件後,重複前面的兩個步驟.
4.若是沒有符合條件的子控件,那麼它本身就是最適合的View
 hitTest方法
做用:尋找最適合的View
參數:當前手指所在的點.產生的事件
返回值:返回誰, 誰就是最適合的View.
何時用調用:只要一個事件,傳遞給一個控件時, 就會調用這個控件的hitTest方法
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
  pointInside方法
做用:判斷point在不在方法調用者上
point:必須是方法調用者的座標系
何時調用:hitTest方法底層會調用這個方法,判斷點在不在控件上.
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    return YES;
}
  hitTest方法底層實現
做用:當一個事件傳遞給當前View的時候就會調用這個方法.
當前手指在屏幕上的點
當前產生的事件
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
   //1.查看本身能不能接收事件
    if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01){
        return nil;
    }
   //2.判斷當前的點在不在本身身上.
    if(![self pointInside:point withEvent:event]){
        return nil;
    }
   //查看本身是否是最適合的view
   //從後往前遍歷本身的子控制器.
    int count = (int)self.subviews.count;
    for (int i = count - 1; i >=0; i--) {
       //取出子控制器.
        UIView *childView = self.subviews[i];
      // 要把當前的點轉換成子控件上的座標點.
        CGPoint childP =  [self convertPoint:point toView:childView];
        UIView *view = [childView hitTest:childP withEvent:event];
        //若是有值,直接返回,返回的就是最適合的View.
        if (view) {
            return view;
        }
    }
    //沒有找到比本身更適合的View.本身就是最適合的View
    return self;
}
  事件的響應
  事件響應過和程
用戶點擊屏幕後產生的一個觸摸事件,通過一系列的傳遞過程後,會找到最合適的視圖控件來處理這個事件,
找到最合適的視圖控件後,就會調用控件的touches方法來做具體的事件處理
那這些touches方法的默認作法是將事件順着響應者鏈條向上傳遞,將事件交給上一個響應者進行處理
什麼是響應者鏈條,響應者對象
  是由多個響應者對象鏈接起來的鏈條.
繼承了UIResponder對象咱們稱之爲響應者對象,也就是能處理事件的對象.
事件傳遞與響應的完整過程 
在產生一個事件時,系統會將該事件加入到一個由UIApplication管理的事件隊列中,
UIApplication會從事件隊列中取出最前面的事件,將它傳遞給先發送事件給應用程序的主窗口.
主窗口會調用hitTest方法尋找最適合的視圖控件,找到後就會調用視圖控件的touches方法來作具體的事情.
當調用touches方法,它的默認作法, 就會將事件順着響應者鏈條往上傳遞,
傳遞給上一個響應者,接着就會調用上一個響應者的touches方法
  如何去尋找上一個響應者
1.若是當前的View是控制器的View,那麼控制器就是上一個響應者.
2.若是當前的View不是控制器的View,那麼它的父控件就是上一個響應者.
3.在視圖層次結構的最頂級視圖,若是也不能處理收到的事件或消息,則其將事件或消息傳遞給window對象進行處理
4.若是window對象也不處理,則其將事件或消息傳遞給UIApplication對象
5.若是UIApplication也不能處理該事件或消息,則將其丟棄
事件傳遞的完整過程
 1.先將事件對象由上往下傳遞(由父控件傳遞給子控件),找到最合適的控件來處理這個事件。
 2.調用最合適控件的touches….方法
 3.若是調用了[super touches….];就會將事件順着響應者鏈條往上傳遞,傳遞給上一個響應者
 4.接着就會調用上一個響應者的touches….方法
相關文章
相關標籤/搜索