• IOS触摸事件


    iOS的输入事件

    触摸事件
    手势识别
    手机摇晃
    一、iOS的输入事件
     
    触摸事件(滑动、点击)
    运动事件(摇一摇、手机倾斜、行走),不需要人为参与的
    远程控制事件(耳机控制手机声音)
    1⃣️iOS事件对象都是UIEvent类的实例
    UIEvent类对事件类型定义了enum常量:
    typedef NS_ENUM(NSInteger, UIEventType){
         UIEventTypeTouches,
         UIEventTypeMotion,
         UIEventRemoteControl,
    };
    触摸事件必须是继承UIResponser的
    二、触摸事件
    1⃣️UIView,有4种处理不同的触摸事件
    UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件。
    1. 一根或者多根手指开始触摸屏幕
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    2.一根或者多根手指在屏幕上移动(随着手指的移动,会持续调用该方法)
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    3.一根或者多根手指离开屏幕
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    4.触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
    复制代码
    #pragma mark - UITouch事件
    #pragma mark 触摸开始
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"触摸开始");
        for (UITouch *touch in touches) {
            NSLog(@"%@", touch);
        }
    }
     
    #pragma mark 触摸移动
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"触摸移动Touch对象个数:%d",[touches count]);
        // 要移动界面上黄颜色的视图
        
        // 1. 得到当前手指的位置
        UITouch *touch = [touches anyObject];
        CGPoint location = [touch locationInView:self.view];
        // 2. 得到上一次手指的位置
        CGPoint preLocation = [touch previousLocationInView:self.view];
        // 3. 计算两个位置之间的偏移
        CGPoint offset = CGPointMake(location.x - preLocation.x, location.y - preLocation.y);
        // 4. 使用计算出来的偏移量,调整视图的位置
        [_demoView setCenter:CGPointMake(_demoView.center.x + offset.x, _demoView.center.y + offset.y)];
        
        // 完整的UITouch事件调试方法
        NSLog(@"触摸移动");
        for (UITouch *touch in touches) {
            NSLog(@"%@", touch);
        }
    }
     
    #pragma mark 触摸结束
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
    {
        // 完整的UITouch事件调试方法
        NSLog(@"触摸完成");
        for (UITouch *touch in touches) {
            NSLog(@"%@", touch);
        }
    }
     
    #pragma mark 触摸中断
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
    {
        // 完整的UITouch事件调试方法
        NSLog(@"触摸中断");
        for (UITouch *touch in touches) {
            NSLog(@"%@", touch);
        }
    }
    复制代码
    2⃣️触摸事件的处理
    如果hit-test视图无法处理事件,则通过响应者链向上传递
    1.如果hit-test视图的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给它的父视图
    2.如果视图或它的控制器无法处理收到的事件或消息,则将其传递给该视图的父视图
    3.每一个在视图继承树中的上层视图如果不能处理收到的事件或消息,则重复上面的步骤1,2
    4.在视图继承树的最上层视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给窗口对象进行处理
    5. 如果窗口对象也不能进行处理,则其将事件或消息传递给UIApplication对象
    6.如果UIApplication也不能处理该事件或消息,则将其丢弃
    当用户点击屏幕时,会产生一个UITouch对象传递给UIApplication,然后由window负责查找最适合相应触摸事件的视图对象(hitTest,pointInside)
    找到合适的视图之后,Touch方法由对应的视图完成,上级视图不再接管
    3⃣️不接受处理事件的三种方法
    不接收用户交互:userInteractionEnabled = NO;
    隐藏:hidden = YES;
    透明:alpha = 0~0.01
    三、手势识别
    1⃣️iOS目前支持的手势识别(6种)
    UITapGestureRecognizer(点按)
    UIPinchGestureRecognizer(捏合)
    UIPanGestureRecognizer(拖动)
    UISwipeGestureRecognizer(轻扫)
    UIRotationGestureRecognizer(旋转)
    UILongPressGestureRecognizer(长按)
    2⃣️手势识别的使用方法(4步)
    通常在视图加载的时候定义(UIGestureRecognizer是抽象类,需要实例化使用)
    创建手势识别实例
    设置手势识别属性,例如手指数量,方向等
    将手势识别附加到指定的视图之上
    编写手势触发响应方法
    3⃣️手势识别的状态(7个)
       1.  // 没有触摸事件发生,所有手势识别的默认状态
        UIGestureRecognizerStatePossible,
        // 一个手势已经开始但尚未改变或者完成时
        UIGestureRecognizerStateBegan,
        // 手势状态改变
        UIGestureRecognizerStateChanged,
        // 手势完成
        UIGestureRecognizerStateEnded,
        // 手势取消,恢复至Possible状态
        UIGestureRecognizerStateCancelled, 
        // 手势失败,恢复至Possible状态
        UIGestureRecognizerStateFailed,
        // 识别到手势识别
        UIGestureRecognizerStateRecognized =UIGestureRecognizerStateEnded 
      2.手势识别的属性
    state——手势状态
    view——手势发生视图
    常用方法
    locationInView 获得手势发生对应视图所在位置
    复制代码
    - (void)viewDidLoad
    {
        [super viewDidLoad];
       
        // 根据实例化方法,我们知道:
        // 1.有一个处理消息的对象,应该是self
        // 2.我们需要定义一个方法,当手势识别检测到的时候,运行
        UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];
        // setNumberOfTapsRequired 点按次数
        [tap setNumberOfTapsRequired:1];
        // setNumberOfTouchesRequired 点按的手指数量
        [tap setNumberOfTouchesRequired:1];
        // 把手势识别增加到视图上
        [self.demoView addGestureRecognizer:tap];
        
       
        UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchAction:)];
        [self.demoView addGestureRecognizer:pinch];
        
       
        UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotationAction:)];
        [self.demoView addGestureRecognizer:rotation];
        
       
        UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];
        [self.demoView addGestureRecognizer:pan];
        
       
        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
        [self.demoView addGestureRecognizer:longPress];
        
       
        // 向左扫
        UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];
        [swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];
        [self.view addGestureRecognizer:swipeLeft];
        // 向右扫
        UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];
        [swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];
        [self.view addGestureRecognizer:swipeRight];
        // 向上扫
        UISwipeGestureRecognizer *swipeTop = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];
        [swipeTop setDirection:UISwipeGestureRecognizerDirectionUp];
        [self.view addGestureRecognizer:swipeTop];
        // 向下扫
        UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];
        [swipeDown setDirection:UISwipeGestureRecognizerDirectionDown];
        [self.view addGestureRecognizer:swipeDown];
    }
     
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
     
    #pragma mark - 轻扫手势
    - (void)swipeAction:(UISwipeGestureRecognizer *)sender
    {
        NSLog(@"%d", sender.direction);
        switch (sender.direction) {
            case UISwipeGestureRecognizerDirectionLeft:
                NSLog(@"向左扫");
                break;
            case UISwipeGestureRecognizerDirectionRight:
                NSLog(@"向右扫");
                break;
            case UISwipeGestureRecognizerDirectionUp:
                NSLog(@"向上扫");
                break;
            case UISwipeGestureRecognizerDirectionDown:
                NSLog(@"向下扫");
                break;
            default:
                break;
        }
    }
     
    #pragma mark - 长按手势
    - (void)longPressAction:(UILongPressGestureRecognizer *)sender
    {
        // 我们可以利用demoView的Tag属性,默认时tag=0
        // 如果tag=0,我们放大一倍,否则,我们缩小一半
        CGFloat scale;
        if (_demoView.tag == 0) {
            scale = 2.0;
            _demoView.tag = 1;
        } else {
            scale = 0.5;
            _demoView.tag = 0;
        }
        
        sender.view.transform = CGAffineTransformScale(sender.view.transform, scale, scale);
    }
     
    #pragma mark - 拖放手势
    - (void)panAction:(UIPanGestureRecognizer *)sender
    {
        // 在拖放手势中是需要考虑手指的状态的UIGestureRecognizerState
        // 在拖放手势中使用的状态是UIGestureRecognizerStateChanged
        // 通常在使用拖放手势的时候,当手指离开的时候,应该做一个很小的动作,提醒用户拖放完成
        if (sender.state == UIGestureRecognizerStateChanged) {
            // locationInView
            [_demoView setCenter:[sender locationInView:self.view]];
        } else if (sender.state == UIGestureRecognizerStateEnded) {
            [_demoView setBackgroundColor:[UIColor yellowColor]];
        }
    }
     
    #pragma mark - 旋转手势
    - (void)rotationAction:(UIRotationGestureRecognizer *)sender
    {
        sender.view.transform = CGAffineTransformRotate(sender.view.transform, sender.rotation);
        
        // 和捏合操作类似,旋转角度同样需要方福伟
        sender.rotation = 0.0f;
    }
     
    #pragma mark - 捏合手势
    - (void)pinchAction:(UIPinchGestureRecognizer *)sender
    {
        // 有关转换的内容,我们在后续动画部分再继续
        sender.view.transform = CGAffineTransformScale(sender.view.transform, sender.scale, sender.scale);
        
        // 缩放功能很简单,但是不要忘记将比例复位
        sender.scale = 1.0f;
        NSLog(@"捏我了");
    }
     
    #pragma mark - 点按手势
    - (void)tapAction:(UITapGestureRecognizer *)sender
    {
       
        NSLog(@"点我了 %@", sender);
    }
     
    #pragma mark - 手势触摸事件
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"触摸事件!");
        // 1. 先取出UITouch对象
        // 2. 判断响应点击的UIView是不是我们需要的
        UITouch *touch = [touches anyObject];
        if ([touch view] == _imageView) {
            NSLog(@"点到图像了!");
        }
    }
    复制代码
    四、手机摇晃
    1. 新建摇晃监听视图ShakeListenerView,并且设置canBecomeFirstResponder返回YES
    - (BOOL)canBecomeFirstResponder
    {
        return YES;
    }
    2. 在Storyboard中将ViewController的View的Class设置为:ShakeListenerView
    3. 在ViewController.m文件中增加:viewDidAppear和viewDidDisappear在视图出现和消失时成为/撤销第一响应者身份
    4. 在视图控制器中增加手势监听方法:
    - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
    {
        if (event.subtype == UIEventSubtypeMotionShake) {
            NSLog(@"shake phone");
        }
    }
    复制代码
    #pragma mark - 要让ViewController支持摇晃,需要写三个方法
    // 1. 成为第一响应者,视图一出现时,就应该成为第一响应者
    - (void)viewDidAppear:(BOOL)animated
    {
        [self.view becomeFirstResponder];
        // 不要忘记去实现父类方法
        [super viewDidAppear:animated];
    }
     
    // 2. 注销第一响应者,视图要关闭的时候,注销
    - (void)viewDidDisappear:(BOOL)animated
    {
        [self.view resignFirstResponder];
        // 不要忘记去实现父类方法
        [super viewDidDisappear:animated];
    }
     
    // 3. 监听并处理移动事件,判断是否摇晃了手机
    - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
    {
        if (motion == UIEventSubtypeMotionShake) {
            NSLog(@"摇啊摇,摇到外婆桥!!!");
        }
    }
  • 相关阅读:
    做汉堡
    结对运算(14曾柏树,15张奇聪)小学生四则运算总结体会
    一个能自动生成小学四则运算题目的程序
    css样式实现立方体制作
    bootstrap导航条+模态对话框+分页样式
    bootstrap 表单+按钮+对话框
    百度地图控件
    百度地图覆盖物0.1版本
    HTML5 javascript 音乐 音频
    html5 javascript 小型计算器
  • 原文地址:https://www.cnblogs.com/mawenqiangios/p/4992499.html
Copyright © 2020-2023  润新知