記錄下:iOS事件的事件的傳遞和響應

王強1476441637000發表於2018-08-09

轉載的這個部落格,詳細見這個部落格 www.jianshu.com/p/2e074db79…

重點

1.UIView不能接收觸控事件的三種情況:
  • 不允許互動:userInteractionEnabled = NO (UIimageView)

  • 隱藏:如果把父控制元件隱藏,那麼子控制元件也會隱藏,隱藏的控制元件不能接受事件

  • 透明度:如果設定一個控制元件的透明度<0.01,會直接影響子控制元件的透明度。alpha:0.0~0.01為透明。

2.父控制元件不能接收觸控事件,子控制元件也不能接受事件

3.如何尋找最合適的view應用如何找到最合適的控制元件來處理事件?

  • 首先判斷主視窗(keyWindow)自己是否能接受觸控事件
  • 觸控點是否在自己身上
  • 從後往前遍歷子控制元件,重複前面的兩個步驟(首先查詢陣列中最後一個元素)
  • 如果沒有符合條件的子控制元件,那麼就認為自己最合適處理

程式碼的分析

// 作用:尋找並返回最合適的view
// UIApplication -> [UIWindow hitTest:withEvent:]尋找最合適的view告訴系統
// point:當前手指觸控的點
// point:是方法呼叫者座標系上的點
- (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] == NO) return nil;
    // 3.從後往前遍歷子控制元件陣列
    //重點
    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 *fitView = [childView hitTest:childP withEvent:event];
        if (fitView) {
            // 如果能找到最合適的view
            return fitView;
        }
    }
    // 4.沒有找到更合適的view,也就是沒有比自己更合適的view
    return self;
}
// 作用:判斷下傳入過來的點在不在方法呼叫者的座標系上
// point:是方法呼叫者座標系上的點
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
 return NO;
}複製程式碼

相關文章