美文网首页
iOS 事件传递 pointInside: withEvent:

iOS 事件传递 pointInside: withEvent:

作者: gaookey | 来源:发表于2020-09-30 23:21 被阅读0次

事件传递相关的函数

- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;   // default returns YES if point is in bounds
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;   // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system

hitTest:底层实现

// 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]) return nil;
    // 3.从后往前遍历自己的子控件,看是否有子控件更适合响应此事件
    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;
        }
    }
    // 没有找到比自己更合适的view
    return self;
}
案例

透过 UITableViewtableHeaderView 点击 tableHeaderView 后的背景图

继承 UITableView 的类 MyTableView 重写 pointInside: withEvent:

#import "MyTableView.h"

@implementation MyTableView

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    if (self.tableHeaderView && CGRectContainsPoint(self.tableHeaderView.frame, point)) {
        return NO;
    }
    return [super pointInside:point withEvent:event];
}

@end
- (void)viewDidLoad {
    [super viewDidLoad];
    
    //可点击的背景图
    UIButton *image = [UIButton buttonWithType:UIButtonTypeCustom];
    image.frame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 200);
    image.backgroundColor = UIColor.lightGrayColor;
    [image setTitle:@"可点击的背景图" forState:UIControlStateNormal];
    [image addTarget:self action:@selector(imageAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:image];
    
    //tableHeaderView
    UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 200)];
    header.backgroundColor = UIColor.clearColor;
    
    //TableView
    MyTableView *table  = [[MyTableView alloc] initWithFrame:self.view.bounds];
    table.delegate = self;
    table.dataSource = self;
    table.tableHeaderView = header;
    table.backgroundColor = UIColor.clearColor;
    [self.view addSubview:table];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 30;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 50;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    static NSString *cellId = @"cellId";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
    }
    cell.textLabel.text = @"事件传递";
    return cell;
}
- (void)imageAction {
    NSLog(@"%s 第%d行 \n %@\n\n",__func__,__LINE__, @"点击了背景图片");
}



改变UIButton有效点击区域

相关文章

网友评论

      本文标题:iOS 事件传递 pointInside: withEvent:

      本文链接:https://www.haomeiwen.com/subject/hfapuktx.html