首页 技术 正文
技术 2022年11月13日
0 收藏 772 点赞 4,160 浏览 11683 个字

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 *)event2.一根或者多根手指在屏幕上移动(随着手指的移动,会持续调用该方法)- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event3.一根或者多根手指离开屏幕- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event4.触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程- (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);     } }

 Swift

 override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {         println("touchesBegan")         //获取touches数量         let numTouches = touches.count         //获取点击屏幕的次数         let tapTouches = (touches as NSSet).anyObject()?.tapCount         //获取事件发生时间         let timestamp = event.timestamp         //获取当前相对于self.view的坐标         let locationPoint = (touches as NSSet).anyObject()?.locationInView(self.view)         //获取上一次相对于self.view的坐标         let previousPoint = (touches as NSSet).anyObject()?.previousLocationInView(self.view)         //允许使用手势         self.view.userInteractionEnabled = true         //支持多点触摸         self.view.multipleTouchEnabled = true         println("\(tapTouches)")         //判断如果有两个触摸点         {             //获取触摸集合             let twoTouches = (touches as NSSet).allObjects             //获取触摸数组             let first:UITouch = twoTouches[] as! UITouch //第1个触摸点             let second:UITouch = twoTouches[]as! UITouch //第2个触摸点             //获取第1个点相对于self.view的坐标             let firstPoint:CGPoint = first.locationInView(self.view)             //获取第1个点相对于self.view的坐标             let secondPoint:CGPoint = second.locationInView(self.view)             //计算两点之间的距离             let deltaX = secondPoint.x - firstPoint.x;             let deltaY = secondPoint.y - firstPoint.y;             let initialDistance = sqrt(deltaX*deltaX + deltaY*deltaY )             println("两点间距离是:\(initialDistance)")         }     }     //手指在移动 //    override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {     //2015年5月2后修改     override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {         println("touchesMoved")     }     //触摸结束 //    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {     //2015年5月2后修改     override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {         println("touchesEnded")     }     //触摸意外终止     //模拟器演示:鼠标拖动的同时,按键盘command+shift+h 相当于点击手机home键,退出应用,触发touchesCancelled事件,在打电话、等情况下也会触发 //    override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) {     //2015年5月2后修改     override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {         println("touchesCancelled")     }     

 2⃣️触摸事件的处理如果hit-test视图无法处理事件,则通过响应者链向上传递1.如果hit-test视图的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给它的父视图2.如果视图或它的控制器无法处理收到的事件或消息,则将其传递给该视图的父视图3.每一个在视图继承树中的上层视图如果不能处理收到的事件或消息,则重复上面的步骤1,24.在视图继承树的最上层视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给窗口对象进行处理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:];     // setNumberOfTouchesRequired 点按的手指数量     [tap setNumberOfTouchesRequired:];     // 把手势识别增加到视图上     [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;     ) {         scale = 2.0;         _demoView.tag = ;     } else {         scale = 0.5;         _demoView.tag = ;     }     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(@"点到图像了!");     } }

Swift:

添加手势

         //点击事件         var atap = UITapGestureRecognizer(target: self, action: "tapDo:")         self.view.addGestureRecognizer(atap)         atap.numberOfTapsRequired =  //单击次数         atap.numberOfTouchesRequired =  //手指个数         //拖动事件         var aPan = UIPanGestureRecognizer(target: self, action: "handlenPan:")         self.view.addGestureRecognizer(aPan)         aPan.minimumNumberOfTouches =  //最少手指个数         aPan.maximumNumberOfTouches =  //最多手指个数         //长按事件         var aLongPress = UILongPressGestureRecognizer(target: self, action: "longPress:")         self.view.addGestureRecognizer(aLongPress)         aLongPress.minimumPressDuration =  //需要长按的时间,最小0.5s         //捏合事件         var aPinch = UIPinchGestureRecognizer(target: self, action: "pinchDo:")         self.view.addGestureRecognizer(aPinch)         //旋转事件         var aRotation = UIRotationGestureRecognizer(target: self, action: "rotatePiece:")         self.view.addGestureRecognizer(aRotation)         //轻扫事件--左轻扫         var leftSwipe = UISwipeGestureRecognizer(target: self, action: "leftSwipe:")         self.view.addGestureRecognizer(leftSwipe)         leftSwipe.direction =  UISwipeGestureRecognizerDirection.Left         //轻扫事件--右轻扫         var rightSwipe = UISwipeGestureRecognizer(target: self, action: "rightSwipe:")         self.view.addGestureRecognizer(rightSwipe)         rightSwipe.direction =  UISwipeGestureRecognizerDirection.Right         //轻扫事件--上轻扫         var upSwipe = UISwipeGestureRecognizer(target: self, action: "upSwipe:")         self.view.addGestureRecognizer(upSwipe)         upSwipe.direction =  UISwipeGestureRecognizerDirection.Up         //轻扫事件--下轻扫         var downSwipe = UISwipeGestureRecognizer(target: self, action: "downSwipe:")         self.view.addGestureRecognizer(downSwipe)         downSwipe.direction =  UISwipeGestureRecognizerDirection.Down     }

实现

     //手势     //点击事件     func tapDo(sender:UITapGestureRecognizer)     {         println("点击事件")     }     //拖动事件     func handlenPan(sender:UIPanGestureRecognizer)     {         println("拖动事件")         if sender.state == .Began         {             //拖动开始         }         else if sender.state == .Changed         {             //拖动过程         }         else if sender.state == .Ended         {             //拖动结束         }     }     //长摁事件     func longPress(sender:UILongPressGestureRecognizer)     {         println("长摁事件")     }     //捏合事件     func pinchDo(sender:UIPinchGestureRecognizer)     {         println("捏合")     }     //旋转事件     func rotatePiece(sender:UIRotationGestureRecognizer)     {         println("旋转")     }     //轻扫事件--左轻扫     func leftSwipe(sender:UISwipeGestureRecognizer)     {         println("左轻扫")     }     //轻扫事件--右轻扫     func rightSwipe(sender:UISwipeGestureRecognizer)     {         println("右轻扫")     }     //轻扫事件--上轻扫     func upSwipe(sender:UISwipeGestureRecognizer)     {         println("上轻扫")     }     //轻扫事件--下轻扫     func downSwipe(sender:UISwipeGestureRecognizer)     {         println("下轻扫")     }

 四、手机摇晃

 . 新建摇晃监听视图ShakeListenerView,并且设置canBecomeFirstResponder返回YES - (BOOL)canBecomeFirstResponder {     return YES; } . 在Storyboard中将ViewController的View的Class设置为:ShakeListenerView . 在ViewController.m文件中增加:viewDidAppear和viewDidDisappear在视图出现和消失时成为/撤销第一响应者身份 . 在视图控制器中增加手势监听方法: - (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(@"摇啊摇,摇到外婆桥!!!");     } }

 

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,086
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,561
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,410
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,183
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,820
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,903