注册
iOS

iOS中的事件

a772d6c363454bfe9c2bf2715f3020c7~tplv-k3u1fbpfcp-zoom-crop-mark:1304:1304:1304:734.awebp?

iOS中的事件

「这是我参与11月更文挑战的第23天,活动详情查看:2021最后一次更文挑战

iOS中的事件

  • 在用户使用APP过程中,会产生各种各样的事件,可以分为三大类
  • 触摸事件(如点击...)
  • 加速器事件(如摇一摇...)
  • 远程控制事件(如耳机可以控制手机音量...)

响应者对象(UIResponder)

说到触摸事件,首先需要了解一个概念:响应者对象

  • 在iOS中不是任何对象都能处理事件,只有继承了 UIResponder 的对象才能接收并处理事件,通常被称为“响应者对象”。如 UIApplicationUIViewControllerUIView 等等

  • UIResponder 内部提供了以下方法来处理事件

  • 触摸事件

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
    - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
    - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
    - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;

  • 加速器事件

    - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
    - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
    - (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;

  • 远程控制方法

    - (void)remoteControlReceivedWithEvent:(UIEvent *)event;


UIView 的触摸事件处理

  • UIView 是 UIResponder 的子类,可以覆盖以下4个方法处理不同的触摸事件

  • 一根或者多根手指开始触摸 view,系统会自动调用 view 的下面方法

    - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;

  • 一根或者多根手指在 view 上移动,系统会自动调用 view 的下面方法

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

  • 一根或者多根手指离开 view,系统会自动调用 view 的下面方法

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

  • 触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程,系统会自动调用 view 的下面方法

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


UITouch

  • 当用户用一根手指触摸屏幕时,会创建一个与手指关联的 UITouch 对象
  • 一根手指对应一个 UITouch 对象
  • UITouch 的作用:保存着跟手指相关的信息,比如触摸的位置、时间、阶段
  • 当手指移动时,系统会更新同一个 UITouch 对象,使之能够一直保存该手指在的触摸位置
  • 当手指离开屏幕时,系统会销毁相应的 UITouch 对象
  • UITouch 相关属性
    • window 触摸产生时所处的窗口
    • view 触摸产生时所处的视图
    • tapCount 短时间内按屏幕的次数,根据 tapCount 判断单击、双击或更多点击
    • timestamp 记录了触摸事件产生或变化的时间,单位是秒
    • phase 当前触摸事件所处的状态
  • UITouch 相关方法
    • 返回值表示触摸在 view 上的位置,这里返回的位置是针对view的坐标系的(以 view 的左上角为原点(0,0)),调用时如果传入的 view 参数是 nil 的话,返回的时触摸点在 window 的位置

      [touch locationInView:view];

    • 该方法记录了上一个点的位置

      [touch previousLocationInView:view];

注:
iPhone开发中,要避免使用双击事件
如果要在一个 view 中监听多个手指,需要设置属性

//需要view支持多个手
view.multipleTouchEnabled = YES;

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"%ld",(long)touches.count); //2
}


UIEvent

  • 每产生一个事件,就会产生一个 UIEvent 对象
  • UIEvent 被称为事件对象,用于记录事件产生的时刻和类型
  • UIEvent 相关属性
    • 事件类型
      • type 枚举类型(触摸事件、加速器事件、远程控制事件)
      • subtype
    • timestamp 事件产生时间
  • UIEvent 相关方法
    • UIEvent 提供相应方法用于获取在某个 view 上面的接触对象(UITouch

简单示例

实现需求:一个按钮可以在屏幕任务拖拽

Kapture 2021-11-22 at 22.49.40.gif

1.自定义一个 UIImageView

@implementation InputImageView

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {        
        UIImage *image = [UIImage imageNamed:@"inputButton"];
        self.image = image;
        self.userInteractionEnabled = YES;
    }
    return self;
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = touches.anyObject;
//获取当前点
CGPoint currentPoint = [touch locationInView:self];
//获取上一个点的位置
CGPoint previousPoint = [touch previousLocationInView:self];
//获取x轴偏移量
    CGFloat offsetX = currentPoint.x - previousPoint.x;
    CGFloat offsetY = currentPoint.y - previousPoint.y;
    //修改view的位置
    self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);
}
@end

2.实际调用

#import "ViewController.h"
#import "InputImageView.h"

@interface ViewController ()
@property (nonatomic,strong) InputImageView *redView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    InputImageView *inputImageView = [[InputImageView alloc]initWithFrame:CGRectMake(150, 150, 56, 56)];
    [self.view addSubview:inputImageView];
}
@end


0 个评论

要回复文章请先登录注册