UIWebView下各种手势识别器的协作处理方案

简介:  前置阅读: 1. iOS私有API(二) UIGestureRecognizerDelegate的两个函数 2. iOS私有API(三) UIWebView下的手势识别器gestureRecognizer UIWebView下有很多的手势,它是怎么管理的呢?主要是两种途径:自管理和委托,即 1.

 前置阅读:

1. iOS私有API(二) UIGestureRecognizerDelegate的两个函数

2. iOS私有API(三) UIWebView下的手势识别器gestureRecognizer

UIWebView下有很多的手势,它是怎么管理的呢?主要是两种途径:自管理和委托,即

1. 继承自UIGestureRecognizer或其子类,重载以下两个函数

// same behavior as the equivalent delegate methods, but can be used by subclasses to define class-wide prevention rules 
// for example, a UITapGestureRecognizer never prevents another UITapGestureRecognizer with a higher tap count 
- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer; 
- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer; 

2. 通过UIGestureRecognizerDelegate,当中还有non-public API。

这里只讨论由UIWebBrowserView和UIWebDocumentView管理的手势。其它assistant所管理的手势,他们的手势的delegate都是各自的assistant,不需要UIWebBrowserView去操心。不过这些assistant和UIWebBrowserView之间都是互相引用的关系,即assistant有成员变量保存UIWebBrowserView的实例指针,究竟assistant在处理手势时让UIWebBrowserView帮了什么忙,这个有空再研究了。

UIWebBrowserView只管理一个手势UIWebTouchEventsGestureRecognizer。这个手势很强势,重载了 canBePreventedByGestureRecognizer 函数,永远返回NO,即不会被任何手势阻止。实际上,TouchEvents手势在其state未变成began之前,就会调用一下delegate(UIWebBrowserView)的action,此时UIWebBrowserView查询到UIWebTouchEventsGestureRecognizer仍是possible state,会做一些清理上次操作的工作。在这个预处理之前,TouchEvents手势已经向内核WebCore查询过是否有js的preventDefault要求了,并把这个信息作为成员变量保存着,故这次的预处理如果发现preventDefault=true,还会做些额外的操作。

UIWebDocumentView是UIWebBrowserView的父类,管理6个手势

UITapGestureRecognizer *_singleTapGestureRecognizer; 
UITapGestureRecognizer *_doubleTapGestureRecognizer; 
UITapGestureRecognizer *_twoFingerDoubleTapGestureRecognizer; 
UILongPressGestureRecognizer *_highlightLongPressGestureRecognizer; 
UILongPressGestureRecognizer *_longPressGestureRecognizer; 
UIPanGestureRecognizer *_twoFingerPanGestureRecognizer; 

而且UIGestureRecognizerDelegate这个protocol是由UIWebDocumentView实现的,确切来说,是由UIWebDocumentView(Interaction)这个category来做的。

我们来看看UIWebDocumentView如何实现UIGestureRecognizerDelegate。

1. - (BOOL)_gestureRecognizer:(id)arg1 shouldReceiveTouch:(id)arg2;

如果arg1为两个doubleTap之一时,返回YES,即双击操作始终接收touch;如果是其它手势,再检测一下这个touch是否点在了插件view上(插件包括:音视频、MapKitView、iAd),如果是,则不接收这个touch。

2. - (BOOL)_gestureRecognizer:(id)arg1 canPreventGestureRecognizer:(id)arg2;

BOOL result = YES; 
    if (m_highlightRecognizer == gestureRecognizer || m_longPressRecognizer == gestureRecognizer) 
    { 
        Class cls = [UIScrollViewPanGestureRecognizer class]; 
        result = [otherGestureRecognizer isKindOfClass:cls] == NO; 
    } 
    return result; 

3. - (BOOL)_gestureRecognizer:(id)arg1 canBePreventedByGestureRecognizer:(id)arg2;

有两种情况返回YES:

情况1:如果arg2不是UITextInteractionAssistant.loupeGesture && arg2不是UIWebSelectionAssistant所管理的1.5次点击手势或长按手势

情况2:arg1不是UIWebDocumentView管理的两个longPress手势

4. - (BOOL)_gestureRecognizer:(id)arg1 shouldRecognizeSimultaneouslyWithGestureRecognizer:(id)arg2;

BOOL result = NO; 
    if ((arg1 == m_highlightRecognizer && arg2 == m_longPressRecognizer) 
        || (arg2 == m_highlightRecognizer && arg1 == m_longPressRecognizer) 
        || (_singleTaparg1 == arg1 && _textSelectionAssistant.singleTapGesture == arg2) 
        || (_textSelectionAssistant.singleTapGesture == arg1 && _singleTaparg1 == arg2)) 
    { 
        result = YES; 
    } 
    return result; 

5. - (BOOL)_gestureRecognizerShouldBegin:(id)arg1;

这个的实现最复杂,需要根据当前touch的位置做各种判断,会使用线程锁进入内核WebCore做查询。进入这个回调时,手势已经接收到足够的touch信息,所以在此回调中去询问手势识别器实例的各个状态时,除了state外都已是对的了。因比较复杂,在别的文章里再说吧。

目录
相关文章
|
Arthas SQL Java
Arthas之WatchSql
在使用Arthas排查线上问题的时候,有些时候我们需要查看某些Sql的生成,如果线上没有完备的APM的话,那么如何临时查看呢,前几篇文章我们分析了Mybatis的插件机制,如果你还记得的话,我们可以通过watch这个插件进行查看。
2728 1
Arthas之WatchSql
|
存储 边缘计算 人工智能
云计算的发展趋势及其在行业中的应用
云计算作为当今信息技术领域的关键驱动力,正在不断演进和创新。从多云模式到边缘计算,从商业到医疗,云计算在多个行业中展现了巨大的应用潜力。未来,随着技术的不断发展,云计算将继续引领着数字化转型的浪潮,为各个行业带来更多的创新和机遇。
1527 0
云计算的发展趋势及其在行业中的应用
|
Linux 数据安全/隐私保护 iOS开发
Linux的root用户,普通用户无法在根录中创建文件,一般在其HOME目录里是不受限的,一旦出了HOME目录,大多数地方,仅有读和执行的权限,ctrl + d回到上一个用户,Exit,su - ro
Linux的root用户,普通用户无法在根录中创建文件,一般在其HOME目录里是不受限的,一旦出了HOME目录,大多数地方,仅有读和执行的权限,ctrl + d回到上一个用户,Exit,su - ro
|
移动开发 JavaScript 小程序
uView Tag 标签
uView Tag 标签
162 1
|
11月前
|
设计模式 前端开发 JavaScript
深入探索研究MVVM架构设计
【10月更文挑战第7天】
283 0
|
负载均衡 Java 测试技术
构建分布式微服务架构:深入探索 Spring Cloud
在当今互联网时代,分布式系统和微服务架构已经成为了构建高效、可扩展应用的标准方式。Spring Cloud,作为 Spring 生态系统的一部分,为开发人员提供了一套强大的工具和库,帮助他们构建稳定、可靠的分布式微服务应用。本文将为您详细介绍 Spring Cloud 的核心概念、组件以及为何它在分布式架构中如此受欢迎。
741 0
|
存储 关系型数据库 MySQL
Percona XtraBackup有哪些优点?
【5月更文挑战第13天】Percona XtraBackup有哪些优点?
165 1
|
人工智能 Linux 云计算
【专访阿里云】云智融合转型期,国产服务器操作系统路在何方?
在云智融合转型趋势引领服务器操作系统迭代升级的时期,国产服务器操作系统社区该如何应对?
|
机器学习/深度学习 算法 Python
LightGBM高级教程:时间序列建模
LightGBM高级教程:时间序列建模【2月更文挑战第7天】
793 0
|
监控 关系型数据库 MySQL
『Jmeter入门万字长文』 | 从环境搭建、脚本设计、执行步骤到生成监控报告完整过程
『Jmeter入门万字长文』 | 从环境搭建、脚本设计、执行步骤到生成监控报告完整过程
969 2