IOS事件傳遞之hitTest:withEvent


一、系統是怎么找到接收觸摸事件發生的視圖的?  --只通過UIView及其子類查找

  0 調用根視圖的hitTtest:withEvent,其的執行過程如下:

  • Ie calls pointInside:withEvent:of self
  • If the return is NO, hitTest:withEvent: returns nil. the end of the story.
  • If the return is YES, it sends hitTest:withEvent: messages to its subviews. it starts from the top-level subview, and continues to other views until a subview returns a non-nil object, or all subviews receive the message.
  • If a subview returns a non-nil object in the first time, the first hitTest:withEvent: returns that object. the end of the story.
  • If no subview returns a non-nil object, the first hitTest:withEvent: returns self

參考:這里

二 、觸摸事件是如何傳遞的?

 

三、hitTest:withEvent應用:

1)父視圖中有布局重疊的且都可響應用戶操作的對象,如:ScrollView and Button,如果Button在ScrollView下面,正常情況下Button是不會成為第一響應者的,如果想讓Button可以響應在其布局內的觸摸事件,可以在Button和ScrollView的父View中重寫hitTest:withEvent方法

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
  CGPoint hitPoint = [_testButton convertPoint:point fromView:self];
  if ([_testButton pointInside:hitPoint withEvent:event]) 
    return _testButton;
  return [super hitTest:point withEvent:event];

}//_testButton是指定響應對象的 弱 引用

參考:這里

 

2)UIView的子類不響應觸摸事件,但其子View可以響應。通過設置userInteractionEnabled=NO,可以使UIView子類不響應觸摸事件,但其會挾持子View,原因見3)

  這時,可以通過重寫hitTest:withEvent來實現:

-(id)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    id hitView = [super hitTest:point withEvent:event];
    if (hitView == self) return nil;
    else return hitView;
}

參考:這里

 

3) userInteractionEnabled = NO的作用:使當前的hitTest:withEvent返回nil,其它的類似屬性還有:Hidden=YES,alpha<0.01,(UIControl中Enabled=NO??),事件發生的點在子View的幾何范圍內,卻超過了父View的幾何范圍(clipsToBounds=NO時可出現此種情況

參考:

1.官方文檔

2.hitTest:withEvent

3.hitTest:withEvent方法流程

 

 


免責聲明!

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



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