1. 程式人生 > 其它 >IOS開發之——事件處理-hiTest(69)

IOS開發之——事件處理-hiTest(69)

技術標籤:IOS

一 概述

  • hiTest方法的介紹
  • hiTest底層實現原理
  • hiTest練習

二 hiTest方法的介紹

2.1 hiTest方法介紹

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

2.2 何時呼叫

當事件傳遞給一個控制元件的時候就會呼叫

2.3 呼叫過程

  • 看視窗是否能接收,如果不能return nil;自己不能接收事件,也不能處理事件,而且也不能把事件傳遞給子控制元件
  • 判斷點在不在視窗上,如果點在視窗上,意味著視窗滿足合適的view

2.4 作用

尋找最合適的view

三 hiTest底層實現原理

3.1 座標系轉換關係

  • 判斷點在不在方法呼叫者的座標系上(point:是方法呼叫者的座標系上的點)

3.2 底層實現原理

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (self.userInteractionEnabled==NO||self.hidden==YES||self.alpha<=0.01) {
        return nil;
    }
    if (![self pointInside:point withEvent:event]) {
        return nil;
    }
    int count=self.subviews.count;
    for (int i=count-1; i>=0; i--) {
        UIView *childView=self.subviews[i];
        //轉換座標系
        CGPoint childPoint=[self convertPoint:point toView:childView];
       UIView *fitView= [childView hitTest:childPoint withEvent:event];
        if (fitView) {
            return fitView;
        }
    }
    return  self;
}

四 hiTest練習

4.1 介面

4.2 要求

  • 介面上有一個Button,Button上方有一個GreenView佈局
  • 點選Button時,Button響應請求
  • 點選Button上方的GreenView時,Button響應請求
  • 點選GreenView上的其他區域時,GreenView響應請求

4.3 程式碼邏輯

GreenView.h

@interface GreenView : UIView
@property (nonatomic,weak) IBOutlet UIButton *button;
@end

GreenView.m

#import "GreenView.h"

@implementation GreenView

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"%s",__func__);
}

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{

    //把自己的點轉換為按鈕座標系上的點
    CGPoint buttonPoint=[self convertPoint:point toView:_button];
    if ([_button pointInside:buttonPoint withEvent:event]) {
        return nil;
    }
    return  [super hitTest:point withEvent:event];
}
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    CGPoint buttonPoint=[self convertPoint:point toView:_button];
    if ([_button pointInside:buttonPoint withEvent:event]) {
        return NO;
    }
    return  [super pointInside:point withEvent:event];
}
@end