史上最全IOS的touch事件手势使用方法

莫河
2023-12-01

以下内容源于本人整理,部分来源于网络,如有侵权行为或错误之处还望指正 请联系邮箱huiyutianshi@qq.com

关于touch事件的

手势和事件都是基于UIRrsponder的
UIResponder包含所有的响应事件:触摸,加速计(摇晃),远程控制(蓝牙) 只有继承与Responder的类才能响应事件,它们被成为响应者,多个响应者组成一个链状层次成为响应者链
———————————————————————————————————————————————————————touch事件
UIControlEventTouchDown           = 1 <<  0,      触摸按下
UIControlEventTouchDownRepeat     = 1 <<  1,      连续按下
UIControlEventTouchDragInside     = 1 <<  2,      区域内拖动比实际大小要大
UIControlEventTouchDragOutside    = 1 <<  3,      区域外拖动 脱离控件很长才会触发
UIControlEventTouchDragEnter      = 1 <<  4,      从区域外向控件内拖动时调用 
UIControlEventTouchDragExit       = 1 <<  5,      从区域内向外拖动时调用
UIControlEventTouchUpInside       = 1 <<  6,      在区域中点击并离开时调用 这个区域非常准确
UIControlEventTouchUpOutside      = 1 <<  7,      在区域内按下 区域外离开的事件  这个区域有点坑  貌似只要涉及拖动 区域就会不准确
UIControlEventTouchCancel         = 1 <<  8,      触摸事件被取消  比如来电 或者信息等紧急事件影响

———————————————————————————————————————————————————————事件的处理顺序
当产生一个事件的时候,会生成一个对应的UIEvent对象,放入到UIApplication得事件列队中,UIApplication按照顺序进行处理,先进先出,UIApplication把事件交给UIWindow,UIWindow会遍历所有的子视图,找到最顶层的视图来处理这个事件UIApplication-UIWindow-UIView,如果顶层视图不处理则事件会向下传递,也就是顶层视图的父视图,如果父视图同样不处理则继续向下传递传递顺序是UIView-UIWindow-UIViewController-UIWindow-UIApplication-AppDelegate如果AppDelegate也没有处理这个事件 则事件被丢弃.

Window是如何寻找触发事件的View的:
当window接收到事件时,会调用所有子视图的H(注1)方法,这个方法会调用自身的P(注2)方法来判断事件触发的点是否在自身的区域内,如在在则返回YES 否则返回NO,如果返回YES则H方法调用自身所有子视图的H方法 知道P方法返回NO 这时H方法返回自身.
//可以重写下面两个方法 来拦截事件消息
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event  注1
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event  注2

//UIApplication中的方法 用于事件的下发 重写此方法可以拦截事件或指定事件接收者
- (void)sendEvent:(UIEvent *)event{

———————————————————————————————————————————————————————事件的处理
三种状态的视图不响应事件:
1.不接受用户交互:userInteractionEnabled = NO
2.隐藏:hidden = YES;
3.透明:alpha = 0.0~0.01
方法名称
说明
isFirstResponder
指示对象是否为第一响应者,这里的第一响应者就是当前有焦点的对象,叫法挺奇怪的,第一次看到真还难以理解这个叫法所表达的意思
nextResponder
下一个响应者,在实现中,一般会返回父级对象
canBecomeFirstResponder
获取一个布尔值,指定对象是否可以获取焦点
becomeFirstResponder
把对象设置为 firstResponder 对象
canResignFirstResponder
对象是否可以取消 firstResponder 对象
resignFirstResponder
取消对象为 firstResponder 对象

输入视图管理相关:
       输入视图是指当对象为 firstResponder 对象时,显示另外一个视图用来处理当前对象的信息输入,如 UITextView 和 UITextField 两个对象,在 UITextField 成为 firstResponder 对象时,会显示一个系统键盘,用来输入信息。这个键盘视图就是一个输入视图了。一共有两个相关的输入视图,一个是 inputView, 另一个是 inputAccessoryView ;  inputView 和 inputAccessoryView 两个属性都指定了相应的视图,则 inputAccessoryView 对象显示在 inputView 对象的上面。
       与输入相关的还有一个 reloadInputViews 方法用来重新载入输入视图。
———————————————————————————————————————————————————————
UITouch:
    •   保存着跟手指相关的信息,比如触摸的位置、时间、阶段
    •   当手指移动时,系统会更新同一个UITouch对象,使之能够一直保存该手指在的触摸位置
    •   当手指离开屏幕时,系统会销毁相应的UITouch对象
UITouch属性:
window:触碰产生时所处的窗口,由于窗口可能发生变化,当前所在的窗口不一定是最开始的窗口。
view:触碰产生时所处的视图。由于视图可能发生变化,当前视图也不一定是最初的视图。
tapCount:短时间内轻击(tap)屏幕的次数,可根据tapCount判断单击、双击或更多的轻击。
timestamp:时间戳记录了触碰事件产生或变化时的时间。单位是秒。
phase:触碰事件在屏幕上有一个周期,即触碰开始、触碰点移动、触碰结束,中途取消。通过phase可以查看当前触碰事件在一个周期中所处的状态。UITouchPhase枚举:
UITouchPhaseBegan
UITouchPhaseMoved
UITouchPhaseStationary
UITouchPhaseEnded
UITouchPhaseCancelled

UITouch方法:
- (CGPoint)locationInView:(UIView *)view; 
    •   返回值表示触摸在view上的位置
    •   这里返回的位置是针对view的坐标系的(以view的左上角为原点(0, 0))
    •   调用时传入的view参数为nil的话,返回的是触摸点在UIWindow的位置
- (CGPoint)previousLocationInView:(UIView *)view; 
    •   该方法记录了前一个触摸点的位置
UIEvent:
    •   每产生一个事件,就会产生一个UIEvent对象
    •   UIEvent:称为事件对象,记录事件产生的时刻和类型
UIEvent属性:
//事件的类型
@property(nonatomic,readonly) UIEventType     type NS_AVAILABLE_IOS(3_0);
@property(nonatomic,readonly) UIEventSubtype  subtype NS_AVAILABLE_IOS(3_0);
//事件产生的时间
@property(nonatomic,readonly) NSTimeInterval  timestamp;

UIEvent方法:
- (NSSet *)allTouches;//获得所有的触摸对象
- (NSSet *)touchesForWindow:(UIWindow *)window;//返回window上所有的触摸对象
- (NSSet *)touchesForView:(UIView *)view;//返回视图上所有的触摸对象
//返回手势上所有的触摸对象
- (NSSet *)touchesForGestureRecognizer:(UIGestureRecognizer *)gesture NS_AVAILABLE_IOS(3_2);

下面是关于手势的

———————————————————————————————————————————————————————UIGestureRecognizer抽象类
UIGestureRecognizer属性:
self.state//返回当前的状态
self.delegate//设置代理
self.enabled //是进行手势识别
self.view  //获取手势绑定的View
self.cancelsTouchesInView //识别到手势后是否发送取消触摸消息给子视图,默认为Yes检测到手势后想取消子视图的响应
self.delaysTouchesBegan //触摸开始时而没有识别出手势时 是否等待识别失败再向子视图发送事件
self.delaysTouchesEnded //正确识别结束后是否发送touchsCancelled消息到子视图
//方法调用的手势识别成功以后并不立即触发,而是等待参数手势识别失败,才触发。如果参数手势识别成功,触发参数手势。
[singleTap requireGestureRecognizerToFail:doubleTap];
//在参数 view 上的触摸位置。如果是多点触摸则输出两点之间的位置
CGPoint point = [recognizer locationInView:self.view];
//返回手势的触摸点数量
- (NSUInteger)numberOfTouches;
//返回坐标点,第一个参数为tauch数组的索引
CGPoint point= [pin locationOfTouch:0 inView:self.view];

———————————————————————————————————————————————————————代理方法
//当一个手势进入可能是手势时(StatePossible)调用,如果返回NO 则放弃匹配 手势识别失败
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
//当一个手势阻止另一个手势时调用,其中一个返回YES表示可以同时触发 如果两个都返回NO则只触发一个
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

———————————————————————————————————————————————————————VIiew中的手势方法
-(void) addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer  增加一个手势。
-(void) removeGestureRecognizer:(UIGestureRecognizer *)getureRecognizer 删除一个手势。
-(BOOL) gestureRecognizerShouldBegan:(UIGestureRecognizer *)gestureRecognizer 询问是否开始执行该手势,默认返回YES
对象创建
UITapGestureRecognizer* tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGesture:)];

———————————————————————————————————————————————————————UIPanGestureRecognizer//平移
self.minimumNumberOfTouches//最少手指个数
self.maximumNumberOfTouches//最多手指个数
//获得手势移动偏移 相对于View 以手势开始为原点
- (CGPoint)translationInView:(UIView *)view;
//设置原点
- (void)setTranslation:(CGPoint)translation inView:(UIView *)view;
//返回手势在视图上的移动速率,像素/秒
- (CGPoint)velocityInView:(UIView *)view;

———————————————————————————————————————————————————————UIPinchGestureRecognizer//捏合
self.scale //捏合比例,原点为1 最小为0 大无限
self.velocity //捏合速率百分比显示

———————————————————————————————————————————————————————UIRotationGestureRecognizer//旋转
self.rotation //旋转角度
self.velocity //速率

———————————————————————————————————————————————————————UISwipeGestureRecognizer//轻扫
self.direction //方向 上下左右 四个方向 默认为1
self.numberOfTouchesRequired //次数

———————————————————————————————————————————————————————UILongPressGestureRecognizer//长按
self.numberOf√√Required //轻击次数
self.numberOfTouchesRequired //长按的时间 最小0.5
self.minimumPressDuration //长按的时间 最小0.5
self.allowableMovement //手指按住允许移动的距离

———————————————————————————————————————————————————————UIScreenEdgePanGestureRecognizer//边缘滑动
self.edges //边界

———————————————————————————————————————————————————————UITapGestureRecognizer//轻击
self.numberOfTapsRequired //轻击次数
self.numberOfTouchesRequired //触摸点数量

———————————————————————————————————————————————————————附录

UIGestureRecognizerStatePossible //0  手势开始,但没有确认是什么手势
UIGestureRecognizerStateBegan   //开始检测到符合当前手势
UIGestureRecognizerStateChanged //手势正在改变坐标
UIGestureRecognizerStateEnded   //手势完成
UIGestureRecognizerStateCancelled//手势取消,被打断
UIGestureRecognizerStateFailed   //手势识别失败,
UIGestureRecognizerStateRecognized //识别完成
 类似资料: