iOS开发学习之触摸事件和手势识别
来源:互联网 发布:mysql怎么修改数据库名 编辑:程序博客网 时间:2024/06/06 18:21
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 触摸开始
1 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event2 {3 NSLog(@"触摸开始");4 for (UITouch *touch in touches) {5 NSLog(@"%@", touch);6 }7 }
#pragma mark 触摸移动
1 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 2 { 3 NSLog(@"触摸移动Touch对象个数:%d",[touches count]); 4 // 要移动界面上黄颜色的视图 5 6 // 1. 得到当前手指的位置 7 UITouch *touch = [touches anyObject]; 8 CGPoint location = [touch locationInView:self.view]; 9 // 2. 得到上一次手指的位置10 CGPoint preLocation = [touch previousLocationInView:self.view];11 // 3. 计算两个位置之间的偏移12 CGPoint offset = CGPointMake(location.x - preLocation.x, location.y - preLocation.y);13 // 4. 使用计算出来的偏移量,调整视图的位置14 [_demoView setCenter:CGPointMake(_demoView.center.x + offset.x, _demoView.center.y + offset.y)];15 16 // 完整的UITouch事件调试方法17 NSLog(@"触摸移动");18 for (UITouch *touch in touches) {19 NSLog(@"%@", touch);20 }21 }22 23 #pragma mark 触摸结束24 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event25 {26 // 完整的UITouch事件调试方法27 NSLog(@"触摸完成");28 for (UITouch *touch in touches) {29 NSLog(@"%@", touch);30 }31 }32 33 #pragma mark 触摸中断34 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event35 {36 // 完整的UITouch事件调试方法37 NSLog(@"触摸中断");38 for (UITouch *touch in touches) {39 NSLog(@"%@", touch);40 }41 }
Swift
1 override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { 2 println("touchesBegan") 3 4 //获取touches数量 5 let numTouches = touches.count 6 7 //获取点击屏幕的次数 8 let tapTouches = (touches as NSSet).anyObject()?.tapCount 9 10 //获取事件发生时间11 let timestamp = event.timestamp12 13 //获取当前相对于self.view的坐标14 let locationPoint = (touches as NSSet).anyObject()?.locationInView(self.view)15 16 //获取上一次相对于self.view的坐标17 let previousPoint = (touches as NSSet).anyObject()?.previousLocationInView(self.view)18 19 //允许使用手势20 self.view.userInteractionEnabled = true21 22 //支持多点触摸23 self.view.multipleTouchEnabled = true24 25 println("\(tapTouches)")26 27 28 //判断如果有两个触摸点29 if touches.count == 230 {31 //获取触摸集合32 let twoTouches = (touches as NSSet).allObjects33 34 //获取触摸数组35 let first:UITouch = twoTouches[0] as! UITouch //第1个触摸点36 let second:UITouch = twoTouches[1]as! UITouch //第2个触摸点37 38 //获取第1个点相对于self.view的坐标39 let firstPoint:CGPoint = first.locationInView(self.view)40 41 //获取第1个点相对于self.view的坐标42 let secondPoint:CGPoint = second.locationInView(self.view)43 44 //计算两点之间的距离45 let deltaX = secondPoint.x - firstPoint.x;46 let deltaY = secondPoint.y - firstPoint.y;47 let initialDistance = sqrt(deltaX*deltaX + deltaY*deltaY )48 49 println("两点间距离是:\(initialDistance)")50 }51 }52 53 //手指在移动54 // override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {55 56 //2015年5月2后修改57 override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {58 59 println("touchesMoved")60 }61 62 //触摸结束63 // override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {64 65 //2015年5月2后修改66 override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {67 68 println("touchesEnded")69 }70 71 //触摸意外终止72 //模拟器演示:鼠标拖动的同时,按键盘command+shift+h 相当于点击手机home键,退出应用,触发touchesCancelled事件,在打电话、等情况下也会触发73 // override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) {74 75 //2015年5月2后修改76 override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {77 78 println("touchesCancelled")79 }80
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 获得手势发生对应视图所在位置
1 - (void)viewDidLoad 2 { 3 [super viewDidLoad]; 4 5 // 根据实例化方法,我们知道: 6 // 1.有一个处理消息的对象,应该是self 7 // 2.我们需要定义一个方法,当手势识别检测到的时候,运行 8 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)]; 9 // setNumberOfTapsRequired 点按次数10 [tap setNumberOfTapsRequired:1];11 // setNumberOfTouchesRequired 点按的手指数量12 [tap setNumberOfTouchesRequired:1];13 // 把手势识别增加到视图上14 [self.demoView addGestureRecognizer:tap];15 16 17 UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchAction:)];18 [self.demoView addGestureRecognizer:pinch];19 20 21 UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotationAction:)];22 [self.demoView addGestureRecognizer:rotation];23 24 25 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];26 [self.demoView addGestureRecognizer:pan];27 28 29 UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];30 [self.demoView addGestureRecognizer:longPress];31 32 33 // 向左扫34 UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];35 [swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];36 [self.view addGestureRecognizer:swipeLeft];37 // 向右扫38 UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];39 [swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];40 [self.view addGestureRecognizer:swipeRight];41 // 向上扫42 UISwipeGestureRecognizer *swipeTop = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];43 [swipeTop setDirection:UISwipeGestureRecognizerDirectionUp];44 [self.view addGestureRecognizer:swipeTop];45 // 向下扫46 UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];47 [swipeDown setDirection:UISwipeGestureRecognizerDirectionDown];48 [self.view addGestureRecognizer:swipeDown];49 }50 51 - (void)didReceiveMemoryWarning52 {53 [super didReceiveMemoryWarning];54 // Dispose of any resources that can be recreated.55 }
#pragma mark - 轻扫手势
1 - (void)swipeAction:(UISwipeGestureRecognizer *)sender 2 { 3 NSLog(@"%d", sender.direction); 4 switch (sender.direction) { 5 case UISwipeGestureRecognizerDirectionLeft: 6 NSLog(@"向左扫"); 7 break; 8 case UISwipeGestureRecognizerDirectionRight: 9 NSLog(@"向右扫");10 break;11 case UISwipeGestureRecognizerDirectionUp:12 NSLog(@"向上扫");13 break;14 case UISwipeGestureRecognizerDirectionDown:15 NSLog(@"向下扫");16 break;17 default:18 break;19 }20 }
#pragma mark - 长按手势
1 - (void)longPressAction:(UILongPressGestureRecognizer *)sender 2 { 3 // 我们可以利用demoView的Tag属性,默认时tag=0 4 // 如果tag=0,我们放大一倍,否则,我们缩小一半 5 CGFloat scale; 6 if (_demoView.tag == 0) { 7 scale = 2.0; 8 _demoView.tag = 1; 9 } else {10 scale = 0.5;11 _demoView.tag = 0;12 }13 14 sender.view.transform = CGAffineTransformScale(sender.view.transform, scale, scale);15 }16
#pragma mark - 拖放手势
1 - (void)panAction:(UIPanGestureRecognizer *)sender 2 { 3 // 在拖放手势中是需要考虑手指的状态的UIGestureRecognizerState 4 // 在拖放手势中使用的状态是UIGestureRecognizerStateChanged 5 // 通常在使用拖放手势的时候,当手指离开的时候,应该做一个很小的动作,提醒用户拖放完成 6 if (sender.state == UIGestureRecognizerStateChanged) { 7 // locationInView 8 [_demoView setCenter:[sender locationInView:self.view]]; 9 } else if (sender.state == UIGestureRecognizerStateEnded) {10 [_demoView setBackgroundColor:[UIColor yellowColor]];11 }12 }
#pragma mark - 旋转手势
1 - (void)rotationAction:(UIRotationGestureRecognizer *)sender 2 { 3 sender.view.transform = CGAffineTransformRotate(sender.view.transform, sender.rotation); 4 5 // 和捏合操作类似,旋转角度同样需要方福伟 6 sender.rotation = 0.0f; 7 } 8 9 #pragma mark - 捏合手势10 - (void)pinchAction:(UIPinchGestureRecognizer *)sender11 {12 // 有关转换的内容,我们在后续动画部分再继续13 sender.view.transform = CGAffineTransformScale(sender.view.transform, sender.scale, sender.scale);14 15 // 缩放功能很简单,但是不要忘记将比例复位16 sender.scale = 1.0f;17 NSLog(@"捏我了");18 }19 20 #pragma mark - 点按手势21 - (void)tapAction:(UITapGestureRecognizer *)sender22 {23 24 NSLog(@"点我了 %@", sender);25 }26 27 #pragma mark - 手势触摸事件28 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event29 {30 NSLog(@"触摸事件!");31 // 1. 先取出UITouch对象32 // 2. 判断响应点击的UIView是不是我们需要的33 UITouch *touch = [touches anyObject];34 if ([touch view] == _imageView) {35 NSLog(@"点到图像了!");36 }37 }
Swift:
添加手势
1 //点击事件 2 var atap = UITapGestureRecognizer(target: self, action: "tapDo:") 3 self.view.addGestureRecognizer(atap) 4 atap.numberOfTapsRequired = 1 //单击次数 5 atap.numberOfTouchesRequired = 1 //手指个数 6 7 //拖动事件 8 var aPan = UIPanGestureRecognizer(target: self, action: "handlenPan:") 9 self.view.addGestureRecognizer(aPan)10 aPan.minimumNumberOfTouches = 1 //最少手指个数11 aPan.maximumNumberOfTouches = 3 //最多手指个数12 13 //长按事件14 var aLongPress = UILongPressGestureRecognizer(target: self, action: "longPress:")15 self.view.addGestureRecognizer(aLongPress)16 aLongPress.minimumPressDuration = 1 //需要长按的时间,最小0.5s17 18 //捏合事件19 var aPinch = UIPinchGestureRecognizer(target: self, action: "pinchDo:")20 self.view.addGestureRecognizer(aPinch)21 22 //旋转事件23 var aRotation = UIRotationGestureRecognizer(target: self, action: "rotatePiece:")24 self.view.addGestureRecognizer(aRotation)25 26 //轻扫事件--左轻扫27 var leftSwipe = UISwipeGestureRecognizer(target: self, action: "leftSwipe:")28 self.view.addGestureRecognizer(leftSwipe)29 leftSwipe.direction = UISwipeGestureRecognizerDirection.Left30 31 //轻扫事件--右轻扫32 var rightSwipe = UISwipeGestureRecognizer(target: self, action: "rightSwipe:")33 self.view.addGestureRecognizer(rightSwipe)34 rightSwipe.direction = UISwipeGestureRecognizerDirection.Right35 36 //轻扫事件--上轻扫37 var upSwipe = UISwipeGestureRecognizer(target: self, action: "upSwipe:")38 self.view.addGestureRecognizer(upSwipe)39 upSwipe.direction = UISwipeGestureRecognizerDirection.Up40 41 //轻扫事件--下轻扫42 var downSwipe = UISwipeGestureRecognizer(target: self, action: "downSwipe:")43 self.view.addGestureRecognizer(downSwipe)44 downSwipe.direction = UISwipeGestureRecognizerDirection.Down45 }
实现
1 2 //手势 3 4 //点击事件 5 func tapDo(sender:UITapGestureRecognizer) 6 { 7 8 println("点击事件") 9 }10 11 //拖动事件12 func handlenPan(sender:UIPanGestureRecognizer)13 {14 println("拖动事件")15 16 if sender.state == .Began17 {18 //拖动开始19 }20 else if sender.state == .Changed21 {22 //拖动过程23 }24 else if sender.state == .Ended25 {26 //拖动结束27 }28 }29 30 //长摁事件31 func longPress(sender:UILongPressGestureRecognizer)32 {33 println("长摁事件")34 35 36 }37 38 //捏合事件39 func pinchDo(sender:UIPinchGestureRecognizer)40 {41 println("捏合")42 }43 44 //旋转事件45 func rotatePiece(sender:UIRotationGestureRecognizer)46 {47 println("旋转")48 }49 50 51 //轻扫事件--左轻扫52 func leftSwipe(sender:UISwipeGestureRecognizer)53 {54 println("左轻扫")55 }56 57 //轻扫事件--右轻扫58 func rightSwipe(sender:UISwipeGestureRecognizer)59 {60 println("右轻扫")61 }62 63 //轻扫事件--上轻扫64 func upSwipe(sender:UISwipeGestureRecognizer)65 {66 println("上轻扫")67 }68 69 //轻扫事件--下轻扫70 func downSwipe(sender:UISwipeGestureRecognizer)71 {72 println("下轻扫")73 }
四、手机摇晃
1 1. 新建摇晃监听视图ShakeListenerView,并且设置canBecomeFirstResponder返回YES 2 - (BOOL)canBecomeFirstResponder 3 { 4 return YES; 5 } 6 2. 在Storyboard中将ViewController的View的Class设置为:ShakeListenerView 7 3. 在ViewController.m文件中增加:viewDidAppear和viewDidDisappear在视图出现和消失时成为/撤销第一响应者身份 8 4. 在视图控制器中增加手势监听方法: 9 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event10 {11 if (event.subtype == UIEventSubtypeMotionShake) {12 NSLog(@"shake phone");13 }14 }15 16 #pragma mark - 要让ViewController支持摇晃,需要写三个方法17 // 1. 成为第一响应者,视图一出现时,就应该成为第一响应者18 - (void)viewDidAppear:(BOOL)animated19 {20 [self.view becomeFirstResponder];21 // 不要忘记去实现父类方法22 [super viewDidAppear:animated];23 }24 25 // 2. 注销第一响应者,视图要关闭的时候,注销26 - (void)viewDidDisappear:(BOOL)animated27 {28 [self.view resignFirstResponder];29 // 不要忘记去实现父类方法30 [super viewDidDisappear:animated];31 }32 33 // 3. 监听并处理移动事件,判断是否摇晃了手机34 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event35 {36 if (motion == UIEventSubtypeMotionShake) {37 NSLog(@"摇啊摇,摇到外婆桥!!!");38 }39 }
0 0
- iOS开发学习之触摸事件和手势识别
- iOS开发学习之触摸事件和手势识别
- iOS开发学习之触摸事件和手势识别
- iOS开发学习之触摸事件和手势识别(转
- iOS开发学习之触摸事件和手势识别
- iOS开发学习之触摸事件和手势识别
- iOS开发学习之触摸事件和手势识别(转)
- ios触摸事件和手势识别
- iOS开发--触摸事件、手势识别、摇晃事件、耳机线控
- IOS之触摸事件和手势
- IOS之触摸事件和手势
- IOS之触摸事件和手势
- IOS之触摸事件和手势
- IOS之触摸事件和手势
- iOS之触摸事件和手势
- iOS之触摸事件和手势
- iOS之触摸事件和手势
- ios自用学习笔记-触摸事件与手势识别
- 第四章 使用OpenCV探测来至运动的结构——Chapter 4:Exploring Structure from Motion Using OpenCV
- REST API 安全设计指南
- Caused by: java.io.FileNotFoundException: dbcpconfig.properties (No such file or directory)
- AppStore被拒的一些原因
- 贪吃蛇(2)
- iOS开发学习之触摸事件和手势识别
- Android实现TextView字符串波浪式跳动
- 贪吃蛇(3)
- OC中类属性的封装方法和类的初始化
- SSH的正向连接和反向连接
- C语言求数组元素中的最小值
- 安卓学习笔记一 —— Activity的一些使用技巧
- SYBASE全库备份方案
- Noip2015总结