iOS--子視圖如何穿透上層視圖響應事件


一、使用方法:
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;

二.背景知識
iOS系統檢測到手指觸摸(Touch)操作時會將其放入當前活動Application的事件隊列,Application會從事件隊列中取出觸摸事件並傳遞給key window(當前接收用戶事件的窗口)處理,window對象首先會使用hitTest:withEvent:方法尋找此次Touch操作初始點所在的視圖(View),即需要將觸摸事件傳遞給其處理的視圖,稱之為hit-test view。
window對象會在首先在view hierarchy的頂級view上調用hitTest:withEvent:,此方法會在視圖層級結構中的每個視圖上調用pointInside:withEvent:,如果pointInside:withEvent:返回YES,則繼續逐級調用,直到找到touch操作發生的位置,這個視圖也就是hit-test view。
三、處理流程
1.首先調用當前視圖的pointInside:withEvent:方法判斷觸摸點是否在當前視圖內;
2.若返回NO,則hitTest:withEvent:返回nil;
3.若返回YES,則向當前視圖的所有子視圖(subviews)發送hitTest:withEvent:消息,所有子視圖的遍歷順序是從
top到bottom,即從subviews數組的末尾向前遍歷,直到有子視圖返回非空對象或者全部子視圖遍歷完畢;
4.若第一次有子視圖返回非空對象,則hitTest:withEvent:方法返回此對象,處理結束;
5.如所有子視圖都返回非,則hitTest:withEvent:方法返回自身(self)。
四、代碼示例

// 在父視圖中實現方法
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
// 1.這是當前點擊的視圖,如果沒有找到合適的響應操作的視圖,則直接返回這個
UIView *view = [super hitTest:point withEvent:event];

// 2.將父視圖坐標轉成我想要響應事件的視圖的坐標
CGPoint buttonPoint = [self convertPoint:point toView:self.button];

// 3.判斷該坐標是否在視圖內部,如果是,則返回該視圖
if ([self.button pointInside:buttonPoint withEvent:event]) {
return self.button;
}
return view;
}

五、注意事項
1.設置hidden = YES;仍然是可以通過該方法響應事件。
2.設置alpha = 0.001;也是可以通過該方法響應事件。
3.子視圖的 origin 即使超出父視圖的范圍也是可以響應事件。
4.設置userInteractionEnabled = NO;則不可以響應事件了。

 

  

by:lm


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM