热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

前置阅读:1.iOS私有API(二)UIGestureRecognizerDelegate的两个函数2.iOS私有API(三)UIWebView下的手势识别器gestureRecognize

 前置阅读:

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外都已是对的了。因比较复杂,在别的文章里再说吧。


推荐阅读
  • 本文提供了一个详尽的前端开发资源列表,涵盖了从基础入门到高级应用的各个方面,包括HTML5、CSS3、JavaScript框架及库、移动开发、API接口、工具与插件等。 ... [详细]
  • 我在尝试将组合框转换为具有自动完成功能时遇到了一个问题,即页面上的列表框也被转换成了自动完成下拉框,而不是保持原有的多选列表框形式。 ... [详细]
  • Flutter 核心技术与混合开发模式深入解析
    本文深入探讨了 Flutter 的核心技术,特别是其混合开发模式,包括统一管理模式和三端分离模式,以及混合栈原理。通过对比不同模式的优缺点,帮助开发者选择最适合项目的混合开发策略。 ... [详细]
  • 本文探讨了在UIScrollView上嵌入Webview时遇到的一个常见问题:点击图片放大并返回后,Webview无法立即滑动。我们将分析问题原因,并提供有效的解决方案。 ... [详细]
  • 当前,众多初创企业对全栈工程师的需求日益增长,但市场中却存在大量所谓的“伪全栈工程师”,尤其是那些仅掌握了Node.js技能的前端开发人员。本文旨在深入探讨全栈工程师在现代技术生态中的真实角色与价值,澄清对这一角色的误解,并强调真正的全栈工程师应具备全面的技术栈和综合解决问题的能力。 ... [详细]
  • 2023年1月28日网络安全热点
    涵盖最新的网络安全动态,包括OpenSSH和WordPress的安全更新、VirtualBox提权漏洞、以及谷歌推出的新证书验证机制等内容。 ... [详细]
  • iOS如何实现手势
    这篇文章主要为大家展示了“iOS如何实现手势”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“iOS ... [详细]
  • 本文探讨了在 APICloud 平台使用 execScript 方法时如何正确传递对象参数,并提供了详细的示例和解释。 ... [详细]
  • 本文探讨了如何使用Scrapy框架构建高效的数据采集系统,以及如何通过异步处理技术提升数据存储的效率。同时,文章还介绍了针对不同网站采用的不同采集策略。 ... [详细]
  • 汇总了2023年7月7日最新的网络安全新闻和技术更新,包括最新的漏洞披露、工具发布及安全事件。 ... [详细]
  • 探讨了在HTML表单中使用元素代替进行表单提交的方法。 ... [详细]
  • 本文将介绍如何在混合开发(Hybrid)应用中实现Native与HTML5的交互,包括基本概念、学习目标以及具体的实现步骤。 ... [详细]
  • 本文出处:炎之铠csdn博客:http:blog.csdn.nettotond炎之铠邮箱:yanzhikai_yjk@qq.com本文原创,转载请注明本出处!前言 ... [详细]
  • LoadRunner中的IP欺骗配置与实践
    为了确保服务器能够有效地区分不同的用户请求,避免多人使用同一IP地址造成的访问限制,可以通过配置IP欺骗来解决这一问题。本文将详细介绍IP欺骗的工作原理及其在LoadRunner中的具体配置步骤。 ... [详细]
  • 本文探讨了如何选择一个合适的序列化版本ID(serialVersionUID),包括使用生成器还是简单的整数,以及在不同情况下应如何处理序列化版本ID。 ... [详细]
author-avatar
l87653644
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有