注意:对于一个手指的触摸,是UITouch每次状态改变的时候都会回调UIResponder相对应的处理方法。对于多个手指的触摸,也许多个UITouch状态的改变一起回调UIResponder的处理方法,也许每个UITouch状态的改变都会回调UIResponder的处理方法,例如,两个点击,可能只有一个touchesBegan的回调,两个touchesEnded的回调同时,多个UIControl状态改变只有一次touchesBegan等方法回调的参数touches里touch的个数我测试的时候只有一个,不要以为所有状态改变的UITouch只有一次回调时都会放到touches参数里。关于多点触摸的处理个人不建议在UITouch的响应机制里去做处理,里面具体原理并不明朗,实际开发中的借鉴也不多,涉及多点触摸使用手势更好。
UIResponder是iOS中用于处理用户事件的API,可以处理触摸事件、按压事件(3D touch)、远程控制事件、硬件运动事件。可以通过touchesBegan、pressesBegan、motionBegan、remoteControlReceivedWithEvent等方法,获取到对应的回调消息。UIResponder不只用来接收事件,还可以处理和传递对应的事件,如果当前响应者不能处理,则转发给其他合适的响应者处理。
应用程序通过响应者来接收和处理事件,响应者可以是继承自UIResponder的任何子类,例如UIView、UIViewController、UIApplication等。当事件来到时,系统会将事件传递给合适的响应者,并且将其成为第一响应者。
第一响应者未处理的事件,将会在响应者链中进行传递,传递规则由UIResponder的nextResponder决定,可以通过重写该属性来决定传递规则。当一个事件到来时,第一响应者没有接收消息,则顺着响应者链向后传递。
Gesture Recognizer 是对底层事件处理的封装,是为了让使用者能够更简单处理事件。
手势分为离散型手势(discrete gestures)和持续型手势(continuous gesture)。
手势响应过程:
手势状态:
UIControl是系统提供的能够以target-action模式处理触摸事件的控件,iOS中UIButton、UISegmentedControl、UISwitch等控件都是UIControl的子类。
值得注意的是,UIConotrol是UIView的子类,因此本身也具备UIResponder应有的身份。
UIControl作为控件类的基类,它是一个抽象基类,我们不能直接使用UIControl类来实例化控件,它只是为控件子类定义一些通用的接口,并提供一些基础实现,以在事件发生时,预处理这些消息并将它们发送到指定目标对象上。
UIControl的触发过程:
四个重要识别方法是在touchesBegan、touchesMoved、touchedEnded、touchesCancelled里回调的。
推测是:endTrackingWithTouch调用后识别了行为,做标记,返回到touchesEnded后,判断本UIControl是否易识别行为,调用行为回调。
App接收到触摸事件后,会被放入当前应用程序的UIApplication维护的事件队列中
由于事件一次只有一个,但是能够响应的事件的响应者众多,所以这就存在一个寻找第一响应者的过程。
调用方法,获取到被点击的视图,也就是第一响应者。
- (UIView )hitTest:(CGPoint)point withEvent:(UIEvent )event;
hitTest:withEvent:方法内部会通过调用pointInside:这个方法,来判断点击区域是否在视图上,是则返回YES,不是则返回NO。
经过Hit-Testing的过程后,UIApplication已经知道了第一响应者是谁,接下来要做的事情就是:
自定义的view的touchesBegan、touchesMoved、touchesEnded、touchedCancelled四个方法重写,记录打印过程,该view上添加tapGestureRecognized手势,该tapGestureRecognized也覆写了这四个方法。
点击view调用打印过程输出:
调用栈:
结合上面的输出和调用栈,我们可能并不能明确的看出有手势的时候点击的过程,不过如果你自己调试,是能得出如下结论的:
UIGestureRecognizer和UITouch的关系可以由UIGestureRecognizer的三个属性影响:cancelsTouchesInView、delaysTouchesBegan、delaysTouchesEnded。
本身就是在UIResponder的UITouchesBegan、UITouchesMoved、UITouchedEnded、UITouchesCancel四个回调中调用的。
UIControl的响应处理并不会影响UIResponder的响应链的处理,但是UIControl会影响另一个UIControl,子视图的UIControl具有优先级。
UIGestureRecognizer和UIControl并没有决定的优先级。
从iOS6开始在控件的父视图上面添加相应的手势,控件就会控制阻止手势行为,比如:
tap 手势在 UIButton,UISwitch,UIStepper,UISegmentControl,UIPageControl;
swipe 手势在 UISlider;
pan 手势在 UISwitch;
其他可能是手势优于控件的行为。
UIResponder有touchesBegan等四个方法,默认向superview传递。
所有需要自定义点击处理逻辑的UIResponder子类要覆盖这四个方法。
点击事件由四个方法处理。
UIButton的处理也是需要经过这四个方法。
UIGestureRecognizer也有touchesBegan等四个方法。
手势不在响应链里,但是也会观察它的view和subView的点击。
UIGestureRecognizer会影响UIResponder的四个响应点击的方法。
默认点击事件响应关键步骤说明:
1)用户手指点击屏幕,经过系统传递到UIApplication, UIApplication通过hitTest:方法找到对应UITouch发生的第一响应者view
2)UIApplication更新手势状态,从第一响应者上的手势到其视图层上所有先辈视图上的手势都会接收这个UITouch来更新手势状态
3)UIApplication将UITouch交给找到的第一响应着view处理
4)UIApplication更新手势状态,识别成功后,会向UITouch的第一响应者发送cancel方法
加上UIControl会让过程变得复杂,关于UIControl的原理,不清楚,也不敢妄下结论,依据网上和实际测试大致推断:
1)它不会影响UITouch本身的响应流程,但是会影响其他UIControl和UIGestureRecognizer的响应
2)自定义的UIControl是和UITouch本身的响应过程是一样的
3)系统定义的UIControl和UIGestureRecognizer同一个优先级,谁先识别出来,另一个就out了,但是UIControl和UIGestureRecognizer有一点不同,它并不会cancel UITouch的流程。
关于UITouch、UIGestureRecognizer、UIControl之间影响说明:
1)UITouch和UIGestureRecognizer:UIGestureRecognizer优先级高于UITouch,由UIGestureRecognizer的三个参数cancelsTouchesInView、delaysTouchesBegan、delaysTouchesEnded决定对UITouch的影响,默认情况下,UIGestureRecognizer识别成功后,会向UITouch发送cancel
避免:
1)尽量不要覆盖重写UIResponder的touchesBegin、touchesMoved、touchesCancelled、touchesEnded这四个方法,如果需要覆盖重写,逻辑应该尽量简单,不宜做复杂的处理,
2)不要自定义UIControl,直接使用系统定义的UIControl
3)UIControl上不要添加UIControl子视图
4)不要依赖UIGestureRecognizer的delayTouchBegin和delayTouchEnded
5)不要自定义UIGestureRecognizer
参考文章:
1) iOS 事件(UITouch、UIControl、UIGestureRecognizer)传递机制
2) Touch Event Handing 教学 — part 1
方法/步骤
1、进入设置--通用,选择通用--辅助功能。
2、辅助功能里面选择“AssistiveTouch”。
3、打开以后你能看见有右下角有个圆点。
4、点击圆点可以看到模拟Home键的各种虚拟快捷键,可以减少Home键的消耗。
5、点击“设备”可以进入另外一层的虚拟手势 *** 作。
6、点击手势可以进入手势的设定,根据个人的习惯设置就可以了。
7、点击个人收藏就可以根据个人喜好自定义手势。
只有更新到 iOS 13 和 iPadOS 13 , iPhone 和 iPad 上都可以使用文本编辑手势
01如何在 iPhone 或 iPad 上使用全新手势进行剪切、复制、粘贴、撤销和重做?
● 复制:三指捏合;
● 剪切:两次三指捏合;
● 粘贴:三指松开;
02● 撤销:左手三指划动(或三指双击);
● 重做:三指向右划动
● 快捷菜单:三指单击
当系统响应三指手势后,将会在屏幕顶端看到提示。
03这里以iPad为例,iPhone 相同 *** 作即可
复制粘贴一段文案,选中文字,三指捏合两次剪切,三指张开粘贴
04撤销
三指往左轻扫撤销
05键盘缩放手势
双指捏合键盘使键盘缩小
支持长按空格移动光标和滑动输入
06在录制过程中遇到了一些如手势 *** 作失败的问题,但是经过适应后还是能够熟练掌握的。目前 iOS 13 还是在测试阶段,如 Pages 、微信等应用的编辑部分手势失效。期待未来正式版能够让解决这些问题提高生产力。
特别提示这个手势在iPad 上使用会更方便
个手指,拍击两次手势
// 创建一个手势识别器
UITapGestureRecognizer oneFingerTwoTaps =
[[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(oneFingerTwoTaps)] autorelease];
// Set required taps and number of touches
[oneFingerTwoTaps setNumberOfTapsRequired:2];
[oneFingerTwoTaps setNumberOfTouchesRequired:1];
// Add the gesture to the view
[[self view] addGestureRecognizer:oneFingerTwoTaps];
消息方法oneFingerTwoTaps
- (void)oneFingerTwoTaps
{
NSLog(@"Action: One finger, two taps");
}
两个手指,拍击两次手势
UITapGestureRecognizer twoFingersTwoTaps =
[[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(twoFingersTwoTaps)] autorelease];
[twoFingersTwoTaps setNumberOfTapsRequired:2];
[twoFingersTwoTaps setNumberOfTouchesRequired:2];
[[self view] addGestureRecognizer:twoFingersTwoTaps];
消息方法twoFingersTwoTaps
- (void)twoFingersTwoTaps {
NSLog(@"Action: Two fingers, two taps");
}
一个手指向上、向下滑动手势
// 向上滑动
UISwipeGestureRecognizer oneFingerSwipeUp =
[[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(oneFingerSwipeUp:)] autorelease];
[oneFingerSwipeUp setDirection:UISwipeGestureRecognizerDirectionUp];
[[self view] addGestureRecognizer:oneFingerSwipeUp];
- (void)oneFingerSwipeUp:(UISwipeGestureRecognizer )recognizer
{
CGPoint point = [recognizer locationInView:[self view]];
NSLog(@"Swipe up - start location: %f,%f", pointx, pointy);
}
// 向下滑动
UISwipeGestureRecognizer oneFingerSwipeDown =
[[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(oneFingerSwipeDown:)] autorelease];
[oneFingerSwipeDown setDirection:UISwipeGestureRecognizerDirectionDown];
[[self view] addGestureRecognizer:oneFingerSwipeDown];
- (void)oneFingerSwipeDown:(UISwipeGestureRecognizer )recognizer
{
CGPoint point = [recognizer locationInView:[self view]];
NSLog(@"Swipe down - start location: %f,%f", pointx, pointy);
}
旋转手势
UIRotationGestureRecognizer twoFingersRotate =
[[[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(twoFingersRotate:)] autorelease];
[[self view] addGestureRecognizer:twoFingersRotate];
- (void)twoFingersRotate:(UIRotationGestureRecognizer )recognizer
{
// Convert the radian value to show the degree of rotation
NSLog(@"Rotation in degrees since last change: %f", [recognizer rotation] (180 / M_PI));
}
向里或向外捏的手势
UIPinchGestureRecognizer twoFingerPinch =
[[[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(twoFingerPinch:)] autorelease];
[[self view] addGestureRecognizer:twoFingerPinch];
- (void)twoFingerPinch:(UIPinchGestureRecognizer )recognizer
{
NSLog(@"Pinch scale: %f", recognizerscale);
}
iOS7手势功能主要有以下几种用法:
1、从左往右手势滑动可返回上一级菜单
在iOS7系统内置内置程序与 *** 作界面上,我们均可以手指需从屏幕边缘左侧手势滑动到右侧,均可以返回到上一菜单;部分非iOS内置程序与官方APP应用可能暂时不支持该功能。
2、iOS7手势上推关闭应用
iOS 7新增的手势功能,有点类似Win8系统的触摸 *** 作,向上手势可关闭打开的应用,另外还可以三指同时上推,这样可同时删除3个后台程序。
3、iOS7手势下推可进行是Spotlight搜索。
4、在Safari浏览器界面,把标签页往左边或者往右边推是关闭标签页。
5、另外iOS7手势功能还可以在短信中,向左手势稍稍拉动可以显示每条短信的具体收发时间。而在日历界面,左右滑动可以切换日期时间等等。
以上就是关于iOS事件机制(点击、手势、UIControl)全部的内容,包括:iOS事件机制(点击、手势、UIControl)、苹果怎么打开手势、如何在 iPhone上使用 iOS 13 的文本编辑手势等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)