iOS事件机制,以及不同手势使用touchesBegan等表现

article/2025/9/21 5:25:05

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

//事件处理方法 UIResponder中定义了一系列对事件的处理方法,他们分别是:
–(void)touchesBegan:(NSSet )touches withEvent:(UIEvent )event
–(void)touchesMoved:(NSSet )touches withEvent:(UIEvent )event
–(void)touchesEnded:(NSSet )touches withEvent:(UIEvent )event
–(void)touchesCancelled:(NSSet )touches withEvent:(UIEvent )event//从方法名字可以知道,他们分别对应了屏幕事件的开始、移动、结束和取消几个阶段,前三个阶段理解都没问题,
//最后一个取消事件的触发时机是在诸如突然来电话或是系统杀进程时调用。
//第一个参数定义了UITouch对象的一个集合(NSSet),它的数量表示了这次事件是几个手指的操作,目前iOS设备支持的多点操作手指数最多是5。
//第二个参数是当前的UIEvent对象。下图展示了一个UIEvent对象与多个UITouch对象之间的关系。
//
//一、点击事件 首先,新建一个自定义的View继承于UIView,并实现上述提到的事件处理方法,我们可以通过判断UITouch的tapCount属性来决定响应单击、双击或是多次点击事件。
//MyView.m
#import "MyView.h"
@implementation MyView
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { }
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { }
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {for (UITouch *aTouch in touches) {if (aTouch.tapCount == 2) {// 处理双击事件[self respondToDoubleTapGesture];}}
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
}
-(void)respondToDoubleTapGesture {NSLog(@"respondToDoubleTapGesture");
}
@end//二、滑动事件 滑动事件一般包括上下滑动和左右滑动,判断是否是一次成功的滑动事件需要考虑一些问题,比如大部分情况下,用户进行一次滑动操作,这次滑动是否是在一条直线上?或者是否是基本能保持一条直线的滑动轨迹。或者判断是上下滑动还是左右滑动等。另外,滑动手势一般有一个起点和一个终点,期间是在屏幕上画出的一个轨迹,所以需要对这两个点进行判断。我们修改上述的MyView.m的代码来实现一次左右滑动的事件响应操作。//MyView.m
#import "MyView.h"
#define HORIZ_SWIPE_DRAG_MIN 12 
//水平滑动最小间距
#define VERT_SWIPE_DRAG_MAX 4
//垂直方向最大偏移量
@implementation MyView
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {UITouch *aTouch = [touches anyObject];// startTouchPosition是一个CGPoint类型的属性,用来存储当前touch事件的位置self.startTouchPosition = [aTouch locationInView:self];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {UITouch *aTouch = [touches anyObject];CGPoint currentTouchPosition = [aTouch locationInView:self];// 判断水平滑动的距离是否达到了设置的最小距离,并且是否是在接近直线的路线上滑动(y轴偏移量)if (fabsf(self.startTouchPosition.x - currentTouchPosition.x) >= HORIZ_SWIPE_DRAG_MIN && fabsf(self.startTouchPosition.y - currentTouchPosition.y) <= VERT_SWIPE_DRAG_MAX) {// 满足if条件则认为是一次成功的滑动事件,根据x坐标变化判断是左滑还是右滑if (self.startTouchPosition.x < currentTouchPosition.x) {[self rightSwipe];//右滑响应方法} else {[self leftSwipe];//左滑响应方法}//重置开始点坐标值self.startTouchPosition = CGPointZero;}
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {//当事件因某些原因取消时,重置开始点坐标值self.startTouchPosition = CGPointZero;
}
-(void)rightSwipe {NSLog(@"rightSwipe");
}
-(void)leftSwipe {NSLog(@"leftSwipe");
}
@end
//三、拖拽事件 在屏幕上我们可以拖动某一个控件(View)进行移动,这种事件成为拖拽事件,其实现原理就是在不改变View的大小尺寸的前提下改变View的显示坐标值,为了达到动态移动的效果,我们可以在move阶段的方法中进行坐标值的动态更改,还是重写MyView.m的事件处理方法,这次在touchesMove方法中进行处理。
//MyView.m
#import "MyView.h"
@implementation MyView
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {UITouch *aTouch = [touches anyObject];//获取当前触摸操作的位置坐标CGPoint loc = [aTouch locationInView:self];//获取上一个触摸点的位置坐标CGPoint prevloc = [aTouch previousLocationInView:self];CGRect myFrame = self.frame;//改变View的x、y坐标值float deltaX = loc.x - prevloc.x;float deltaY = loc.y - prevloc.y;myFrame.origin.x += deltaX;myFrame.origin.y += deltaY;//重新设置View的显示位置[self setFrame:myFrame];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
}
@end
//四、双指缩放 之前提到过UIEvent包含了一系列的UITouch对象构成一次事件,当设计多点触控操作时,可与对UIEvent对象内的UITouch对象进行处理,比如实现一个双指缩放的功能。
//MyView.m
#import "MyView.h"
@implementation MyView {BOOL pinchZoom;CGFloat previousDistance;CGFloat zoomFactor;
}
-(id)init {self = [super init];if (self) {pinchZoom = NO;//缩放前两个触摸点间的距离previousDistance = 0.0f;zoomFactor = 1.0f;}return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {if(event.allTouches.count == 2) {pinchZoom = YES;NSArray *touches = [event.allTouches allObjects];//接收两个手指的触摸操作CGPoint pointOne = [[touches objectAtIndex:0] locationInView:self];CGPoint pointTwo = [[touches objectAtIndex:1] locationInView:self];//计算出缩放前后两个手指间的距离绝对值(勾股定理)previousDistance = sqrt(pow(pointOne.x - pointTwo.x, 2.0f) + pow(pointOne.y - pointTwo.y, 2.0f));} else {pinchZoom = NO;}
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {if(YES == pinchZoom && event.allTouches.count == 2) {NSArray *touches = [event.allTouches allObjects];CGPoint pointOne = [[touches objectAtIndex:0] locationInView:self];CGPoint pointTwo = [[touches objectAtIndex:1] locationInView:self];//两个手指移动过程中,两点之间距离CGFloat distance = sqrt(pow(pointOne.x - pointTwo.x, 2.0f) + pow(pointOne.y - pointTwo.y, 2.0f));//换算出缩放比例zoomFactor += (distance - previousDistance) / previousDistance;zoomFactor = fabs(zoomFactor);previousDistance = distance;//缩放self.layer.transform = CATransform3DMakeScale(zoomFactor, zoomFactor, 1.0f);}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {if(event.allTouches.count != 2) {pinchZoom = NO;previousDistance = 0.0f;}
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
}
@end
转自:http://www.cnblogs.com/zhw511006/p/3517249.html 上面实现的方式有一点不足之处就是必须两个手指同时触摸按下才能达到缩放的效果,并不能达到相册里面那样一个手指触摸后,另一个手指按下也可以缩放。如果需要达到和相册照片缩放的效果,需要同时控制begin、move、end几个阶段的事件处理。这个不足就留给感兴趣的同学自己去实现了。

 

转载于:https://my.oschina.net/iceTear/blog/1505392


http://chatgpt.dhexx.cn/article/pkIX0BoG.shtml

相关文章

ios事件-触摸事件3(UIButton 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()的关系)

ios事件-触摸事件3(UIButton 和 pointInSide()、hitTest()、touchesBegan()、touchesMoved()、touchesEnded()、touchesCancelled()的关系) 先看效果图 本文中&#xff0c;凡是看到xxx(),即表示xxx是一个函数或者方法&#xff01;&#xff01;&#xff01;事件分为事件传递和事…

【application Extension 之TodayExtension】扩展与宿主App之间共享数据有两种方式

文章目录 前言I 、点击跳转到APPII、扩展与宿主App之间共享数据有两种方式:2.1.通过NSUserDefaults2.2. 通过一个扩展与App都可以访问的共享容器,来存放文件,数据(Core Data, Sqlite等都可以存放在这个共享的容器中)III、扩展Widget高度前言

PHP-递归算法

在PHP开发过程中&#xff0c;递归算法通常用于无限极分类。那么所谓递归就是一种函数调用自身的机制。简单来说就是在函数体内直接或间接自己调用自己&#xff0c;但需要设置自调用的条件&#xff0c;若满足条件&#xff0c;则调用函数本身&#xff0c;若不满足则终止本函数的自…

php 递归 递归方式与算法

先设置数据在本地数据库&#xff0c;设置前要先了解pid字段的关系。如果做成菜单还需添加一个路由字段&#xff0c;自行定义。 第一种方式 先将数据提取出转换成数组。重点是Yarray方法里的递归方式。 接下来进行解析方式。 重点&#xff1a;一定要在进行递归之前声明一个静态…

关于递归函数

递归函数概念 递归就是一个函数在它的函数体内调用它自身。执行递归函数将反复调用其自身&#xff0c;每调用一次就进入新的一层。递归函数必须有结束条件。 当函数在一直递推&#xff0c;直到遇到墙后返回&#xff0c;这个墙就是结束条件。 所以递归要有两个要素&#xff0c;…

php递归函数详解

很多同学在学习递归函数的时候会感到头晕&#xff0c;无法搞清楚递归函数的原理和运行机制&#xff0c;本文将给大家详细讲解递归函数的运行机制和运用。 那什么是递归函数呢&#xff1f; 递归函数即为自调用函数&#xff0c;在函数体内直接或间接自己调用自己&#xff0c;但需…

递归函数

一、基本的递归函数 首先先来了解下C程序在内存中的组织方式&#xff0c;基本上来说一个可执行的程序在内存中有4个区域组成&#xff1a;代码段、静态数据区、堆与栈。代码段包含程序运行时所执行的机器指令&#xff1b;静态数据区是包含在程序的生命周期内的一直持续的数据&a…

PHP 递归函数的理解

很多同学在学习递归函数的时候会感到头晕&#xff0c;无法搞清楚递归函数的原理和运行机制&#xff0c;本文将给大家详细讲解递归函数的运行机制和运用。那什么是递归函数呢&#xff1f;递归函数即为自调用函数&#xff0c;在函数体内直接或间接自己调用自己&#xff0c;但需要…

PHP中使用递归函数

下面是使用递归函数的一个小例子。 目的是根据parent_id和task_id对task进行分类。 具体实现&#xff1a; <?php //连接数据库&#xff0c;使用前几天创建的数据库连接文件进行连接&#xff0c;如果没有这个文件可以去我的博客里找一下 require_once(./db.php); $conn…

PHP递归详解

递归 递归是一种函数调用自身的机制递归必须要有边界条件&#xff0c;也就是递归出口&#xff08;退出递归&#xff09;递归前进段和递归返回段&#xff0c;也就是最后得到的值当边界条件不满足时&#xff0c;递归前进&#xff1b;当边界条件&#xff08;递归出口&#xff09;…

PHP 递归函数

递归函数即自调用函数&#xff0c;在函数体内部直接或间接的自己调用自己&#xff0c;即函数的嵌套调用就是函数本身。通常 在此类型的函数体中会附加一个条件判断&#xff0c;以判断是否需要执行递归调用&#xff0c;并且在特定的条件下终止函数的递归 调用动作&#xff0c;…

软件设计师考试感想随笔

带着紧张期待的心情查询了2021年下半年的软件设计师考试成绩&#xff0c;上午55分&#xff0c;下午66分&#xff0c;对这个成绩也算预料之中&#xff0c;因为我刚考完不到一个星期就在网上搜了答案对了成绩。 刚开始的时候买的纸质教程&#xff0c;厚厚的一本&#xff0c;还没看…

软考中级,软件设计师考试那些内容,考试大纲什么的?

一、中级软件设计师科目包括&#xff1a; &#xff08;1&#xff09;计算机与软件工程知识&#xff0c;考试时间为150分钟&#xff0c;笔试&#xff0c;选择题&#xff1b; &#xff08;2&#xff09;软件设计&#xff0c;考试时间为150分钟&#xff0c;笔试&#xff0c;问答…

软考软件设计师中级考试大纲(附题型举例)

软件设计师考试大纲 一、考 试 说 明 1&#xff0e;考试目标 通过本考试的合格人员能根据软件开发项目管理和软件工程的要求&#xff0c;按照系统总体设计规格说明书进行软件设计&#xff0c;编写程序设计规格说明书等相应的文档&#xff0c;组织和指导程序员编写、调试程序…

软考中级–软件设计师考试大纲

软考中级–软件设计师考试大纲 考试场数&#xff1a;上午&#xff08;基础理论&#xff0c;75个选择题&#xff0c;1空1分&#xff09;、下午&#xff08;案例分析&#xff0c;五个解答题&#xff0c;每道题15分&#xff09; 分数线&#xff1a; 上下午满分都是75分&#xff…

软件设计师提纲+复习资料整理(上午题)

文章目录 软件设计师考试大纲上午题&#xff08;选择题&#xff09;一、计算机组成原理考点&#xff1a;CPU结构组成考点&#xff1a;原码、反码、补码定点整数范围考点&#xff1a;浮点数表示考点&#xff1a;RISC和CISC计算机的区别考点&#xff1a;奇校验与偶校验考点&#…

【软考-软件设计师精华知识点笔记】考试大纲及题型介绍

前言 今年上半年参加了软件设计师考试&#xff0c;考完感觉稳了&#xff08;成绩下来已经通过了&#xff09;&#xff0c;考试内容与我学习的内容基本一致&#xff0c;因此感觉自己的笔记可以帮助其他准备考试的童鞋。总共十一章的笔记&#xff0c;已完成。如果未来有机会&…

struts2拦截器定义

为什么需要拦截器&#xff1a; 早起MVC框架将一些通用操作写死在核心控制器中&#xff0c;致使框架灵活性不足&#xff0c;可扩展性降低。Struts2将核心功能放在多个拦截器中实现&#xff0c;拦截器可自由选择和组合&#xff0c;增强了灵活性&#xff0c;有利于系统的解耦。 什…