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


推荐阅读
  • 这篇文章将揭示 Vue 和 React 组件库中五个鲜为人知的强大工具。这些工具均以纯 JavaScript 实现,功能卓越。其中,async-validator 是一个数据验证插件,不仅预置了 URL 和电子邮件的验证规则,还支持异步验证功能。 ... [详细]
  • 本文介绍了如何通过掌握 IScroll 技巧来实现流畅的上拉加载和下拉刷新功能。首先,需要按正确的顺序引入相关文件:1. Zepto;2. iScroll.js;3. scroll-probe.js。此外,还提供了完整的代码示例,可在 GitHub 仓库中查看。通过这些步骤,开发者可以轻松实现高效、流畅的滚动效果,提升用户体验。 ... [详细]
  • 本文深入探讨了Android事件分发机制的源代码,重点分析了DecorView作为Activity根布局的角色及其在事件传递中的作用。同时,详细解析了PhoneWindow在Activity窗口管理中的关键功能,以及它如何与DecorView协同工作,确保用户交互事件的高效处理。 ... [详细]
  • 本文介绍如何在 Android 中自定义加载对话框 CustomProgressDialog,包括自定义 View 类和 XML 布局文件的详细步骤。 ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • 技术分享:深入解析GestureDetector手势识别机制
    技术分享:深入解析GestureDetector手势识别机制 ... [详细]
  • 地图集成方法与应用 ... [详细]
  • 在探讨C语言编程文本编辑器的最佳选择与专业推荐时,本文将引导读者构建一个基础的文本编辑器程序。该程序不仅能够打开并显示文本文件的内容及其路径,还集成了菜单和工具栏功能,为用户提供更加便捷的操作体验。通过本案例的学习,读者可以深入了解文本编辑器的核心实现机制。 ... [详细]
  • 深入解析JavaScript中的函数防抖与节流技术及其应用场景
    本文深入探讨了JavaScript中函数防抖和节流技术的原理及应用场景。通过详细的示例代码,全面解析了这两种优化方法在实际开发中的重要作用,为开发者提供了宝贵的参考和实践指导。 ... [详细]
  • 探讨 `org.openide.windows.TopComponent.componentOpened()` 方法的应用及其代码实例分析 ... [详细]
  • 在iOS平台上,应用的流畅操作体验一直备受赞誉。然而,过去开发者往往将更多精力集中在功能实现上,而对性能优化的关注相对较少。本文深入探讨了iOS应用性能优化的关键要点与实践方法,旨在帮助开发者提升应用的响应速度、降低功耗,并改善整体用户体验。通过具体案例分析和技术解析,文章提供了实用的优化策略,包括代码层面的改进、资源管理优化以及界面渲染效率的提升等。 ... [详细]
  • 整合百度UEditor编辑器于ASP后端的实现步骤与技巧
    随着微软停止对XP系统的支持,公司已全面升级至Windows 7。早期网站创建时使用的编辑器仅兼容IE6浏览器,而如今系统更新后,原有的编辑器已无法满足新环境的需求。本文详细介绍了如何将百度UEditor编辑器整合到ASP后端,包括实现步骤和实用技巧,确保网站在新系统下仍能高效运行并提供良好的用户体验。 ... [详细]
  • 本文介绍了如何使用 Node.js 和 Express(4.x 及以上版本)构建高效的文件上传功能。通过引入 `multer` 中间件,可以轻松实现文件上传。首先,需要通过 `npm install multer` 安装该中间件。接着,在 Express 应用中配置 `multer`,以处理多部分表单数据。本文详细讲解了 `multer` 的基本用法和高级配置,帮助开发者快速搭建稳定可靠的文件上传服务。 ... [详细]
  • 掌握Android UI设计:利用ZoomControls实现图片缩放功能
    本文介绍了如何在Android应用中通过使用ZoomControls组件来实现图片的缩放功能。ZoomControls提供了一种简单且直观的方式,让用户可以通过点击放大和缩小按钮来调整图片的显示大小。文章详细讲解了ZoomControls的基本用法、布局设置以及与ImageView的结合使用方法,适合初学者快速掌握Android UI设计中的这一重要功能。 ... [详细]
  • 开发笔记:深入解析Android自定义控件——Button的72种变形技巧
    开发笔记:深入解析Android自定义控件——Button的72种变形技巧 ... [详细]
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社区 版权所有