當一個控件不能接收事件時通常有如下幾種狀況
1.不接收用戶交互userInteractionEnabled = NO
2.當一個控件隱藏時Hidden = YES
3.當一個控件的Alpha = 0.0~0.01
的時候ios
####注意:UIImageView
以及它的子控件默認是不能接收觸摸事件的ide
用戶點擊屏幕產生的一個觸摸事件,通過一系列的傳遞過程後,會找到一個最適合的視圖來處理事件.找到最合適的視圖控件後,就會調用控件的touches
方法來做具體的事件處理.touches
的默認作法是將事件順着響應者鏈條向上傳遞,將事件交給上一個響應者處理code
1.先判斷本身是否能接收觸摸事件
2.再判斷觸摸的當前點在不在本身身上
3.若是在本身身上,它會從後往前遍歷子控件,遍歷出每個控件後,重啓前兩步
4.若是沒有符合條件的子控件,那麼自身就是最合適的View對象
//做用:尋找最適合的View //何時調用:當事件傳遞給當前View時就會調用這個方法 -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{ UIView *fitView = [super hitTest:point withEvent:event]; NSLog(@"%@",fitView); return fitView; } //做用:判斷觸摸點在不在當前的View上. //何時調用:在hitTest方法當中會自動調用這個方法. //注意:point必須得要跟當前View同一個座標系. -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{ return YES; }
那麼hitTest: withEvent:
方法底層是如何實現的呢?繼承
// 判斷本身可否接收事件 if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01){ return nil; } // 觸摸點在不在本身身上 if ([self pointInside:point withEvent:event] == NO) { return nil; } // 從後往前遍歷本身的子控件(重複前面的兩個步驟) int count = (int)self.subviews.count; for (int i = count -1; i >= 0; i--) { UIView *childV = self.subviews[i]; // point必須得要跟childV相同的座標系. // 把point轉換childV座標系上面的點 CGPoint childP = [self convertPoint:point toView:childV]; UIView *fitView = [childV hitTest:childP withEvent:event]; if (fitView) { return fitView; } } // 若是沒有符合條件的子控件,那麼就本身最適合處理 return self;