iOS开发

iOS 之事件

2019-05-09  本文已影响0人  追逐_chase

iOS的事件分类

触摸事件处理的的方法

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

UITouch触摸对象常用的方法和属性

-1 - (CGPoint)locationInView:(nullable UIView *)view; 返回当前触摸对象的View的坐标点
-2 - (CGPoint)previousLocationInView:(nullable UIView *)view;返回当前触摸View的上一次的触摸点

@property(nonatomic,readonly) NSTimeInterval      timestamp;
@property(nonatomic,readonly) UITouchPhase        phase;
@property(nonatomic,readonly) NSUInteger          tapCount;   // touch down within a certain point within a certain amount of time
@property(nonatomic,readonly) UITouchType         type

demo例子(UIView的拖拽)

给控制器,添加一个子控件UIView,在UIView中实现 触摸事件的处理方法


- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //获取到UITouch对象
    UITouch *touch = [touches anyObject];
    //当前的触摸点
    CGPoint currentPoint = [touch locationInView:self];
    //获取到上一次移动的触摸点
    CGPoint prePoint = [touch previousLocationInView:self];
    //移动的差值
    CGFloat offsetX = currentPoint.x - prePoint.x;
    CGFloat offsetY = currentPoint.y - prePoint.y;

  //平移(transform), 在原来平移的基础上平移
    self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);

}
01_uiview的平移.gif

事件的传递

注意: 事件的传递的一层一层的,从父控件传递给子控件,如果父控件不能接受事件的传递,那么子控件也就不能接受触摸事件

02.png

当点击绿色的View事件的传递过程为
UIApplication ->UIWindow->粉色View->紫色View ->绿色View

//1.控件的属性,不可以交互的
userInteractionEnabled = no

//2.隐藏控件
hidden = yes

//3.透明度小于 0.01的控件

//上述的3中情况,不可以处理事件

寻找最合适的View处理事件

操作判断

需要实现的方法

//一个事件传递给这个View的时候,这个方法就会被调用
//返回的值,就是最合适的View
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    
    return [super hitTest:point withEvent:event];
    
}


//判断当前点是不是在自己身上
//当hitTest:withEvent:调用的时候,内部就会调用这个方法
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event{
    
    return YES;
}

hitTest: withEvent:方法的内部原理实现

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    //内部实现方法
    
    //1.判断是否可以接受事件
    
    if (self.hidden == YES || self.alpha <= 0.01 || self.userInteractionEnabled == NO) {
        
        return nil;
    }
    
    //2.判断触摸点是否在自己身上
    if (![self pointInside:point withEvent:event]) {
        
        return nil;
    }
    
    //3.从后向前遍历子控件

    int count = (int)self.subviews.count;
    
    for (int i = count - 1; i >= 0; i--) {
        //获取到子控件
        UIView *chiledView = self.subviews[i];
        //转化坐标点 到子控件上
        CGPoint childPoint =  [self convertPoint:point toView:chiledView];
        //获取View
        UIView *fitView = [chiledView hitTest:childPoint withEvent:event];
        
        //如果存在,就是最合适的view
        if (fitView) {
            
            return fitView;
        }
    
    }
    
    
    //没有找到合适的View,返回自己
    return self;
    
}

注意:如果在判断的时候是 子控件 需要转化子控件的 坐标点

上一篇 下一篇

猜你喜欢

热点阅读