02.2--iOS中的事件-触摸事件

2018-11-26  本文已影响0人  weyan

一、UIView的触摸事件

1、UIView的拖拽

#import "RedView.h"

@implementation RedView

//当开始触摸是自动调用
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    NSLog(@"%s",__func__);
}

//当触摸移动时调用
//NSArray:集合里面存入的元素都是有序的
//NSArray:集合里面存入的元素都是无序的
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
     NSLog(@"%s",__func__);
    
    //获取UITouch对象
    UITouch *touch = [touches anyObject];
    
    //上一个点:prePoint
    //当前点:curPoint
    //获取上一点
    CGPoint preP = [touch previousLocationInView:self];
    //获取当前点
    CGPoint cur = [touch locationInView:self];
  
    NSLog(@"preP = %@",NSStringFromCGPoint(preP));
    NSLog(@"cur = %@",NSStringFromCGPoint(cur));

    //x偏移量 = 当前点.x – 上一个点的.x
    CGFloat offsetX = cur.x - preP.x;
    //y偏移量 = 当前点.y – 上一个点的.y
    CGFloat offsetY = cur.y - preP.y;

    //让当前View跟着手指移动
    //Transform->平移
    self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);

}

//当手指离开时调用
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"%s",__func__);
}

//当系统事件打断当前的触摸事件时调用
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

}

@end

2、事件的产生和传递

#import "WhiteView.h"

@implementation WhiteView

//5.找到后调用touchesBegan:方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    NSLog(@"%@----touch",[self class]);
}

//什么时候调用:当事件传递给当前View时, 会调用当前Veiw的hitTest方法.
//作用:寻找最适合的View.
//返回值:返回谁,谁就是最适合的view,谁就响应事件,就会调用谁的touches方法
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    
    //1.判断自己能否接收事件
    //2.点在不在自己身上(通过调用下面的pointInside:方法)
    
    //3.从后往前遍历自己了的子控件,把事件传递给子控件,调用子控件的hitTest,
    //4.如果子控件没有找到最适合的View,那么自己就是最适合的View.
    return  [super hitTest:point withEvent:event];
    
}


//作用:点在不在自己身上,调用当前View一个方法(pointInside:)
//什么时候调用:在hitTest内部调用的
//返回值:YES在当前View身上, NO,不在
//point:当前触摸点
//注意:必须得要跟方法调用者在同一个坐标系
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return YES;
}


@end
#import "XMGWindow.h"

@implementation XMGWindow

- (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.从后往前遍历自己的子控件,把事件传递给子控件,调用子控件的hitTest,
    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) {
            return fitView;
        }
    }
    //4.如果子控件没有找到最适合的View,那么自己就是最适合的View.
    return self;
    
}

@end
#import "YellorView.h"

@interface YellorView ()
@property (nonatomic,weak) IBOutlet UIButton *redBtn;
@end

@implementation YellorView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    
    //判断点在不在红色按钮身上, 如果在,直接返回红色按钮
    CGPoint redP = [self convertPoint:point toView:self.redBtn];
    
    if ([self.redBtn pointInside:redP withEvent:event]) {
        return self.redBtn;
    }
    //否则保持原有做法.
    return [super hitTest:point withEvent:event];
    
}

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

3、事件响应(响应者链条)

上一篇下一篇

猜你喜欢

热点阅读