-
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);}}复制代码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 =UIGestureRecognizerStateEnded2.手势识别的属性state——手势状态view——手势发生视图常用方法locationInView 获得手势发生对应视图所在位置复制代码- (void)viewDidLoad{[super viewDidLoad];/**1. 演示点按手势*/// 根据实例化方法,我们知道:// 1.有一个处理消息的对象,应该是self// 2.我们需要定义一个方法,当手势识别检测到的时候,运行UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];// setNumberOfTapsRequired 点按次数[tap setNumberOfTapsRequired:1];// setNumberOfTouchesRequired 点按的手指数量[tap setNumberOfTouchesRequired:1];// 把手势识别增加到视图上[self.demoView addGestureRecognizer:tap];/**2. 捏合点按手势*/UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchAction:)];[self.demoView addGestureRecognizer:pinch];/**3. 旋转点按手势*/UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotationAction:)];[self.demoView addGestureRecognizer:rotation];/**4. 拖放点按手势*/UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];[self.demoView addGestureRecognizer:pan];/**5. 长按手势*/UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];[self.demoView addGestureRecognizer:longPress];/**6. 轻扫手势关于轻扫手势,是需要指定方向的,如果你不指定方向,那么只能接收到的向右方向的轻扫事件*/// 向左扫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{/**在开发过程中,如果没有什么必要,最好不要对一个UI控件,既使用触摸,又使用手势。*/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设置为:ShakeListenerView3. 在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(@"摇啊摇,摇到外婆桥!!!");}}
iOS开发学习之触摸事件和手势识别
最新推荐文章于 2023-01-11 18:01:27 发布