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


推荐阅读
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文介绍了Sencha Touch的学习使用心得,主要包括搭建项目框架的过程。作者强调了使用MVC模式的重要性,并提供了一个干净的引用示例。文章还介绍了Index.html页面的作用,以及如何通过链接样式表来改变全局风格。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 关于extjs开发实战pdf的信息
    本文目录一览:1、extjs实用开发指南2、本 ... [详细]
  • 1.webkit内核中的一些私有的meta标签,这些meta标签在开发webapp时起到非常重要的作用(1) ... [详细]
  • html结构 ... [详细]
  • 2048小游戏小记
    1。游戏界面布局由textview1与textview2来显示分数,2048游戏主界面由gridlayout组成,底部添加Button重启游戏。2.创建游戏主类Gameview在构 ... [详细]
  • Android Studio中的IBM MobileFirst Compile问题 - IBM MobileFirst Compile in Android Studio Issue
    IbuiltaMultipageapplicationbyusingIBMMobileFirst,accordingto据我所知,我使用IBMMobileFirst构建了一个 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • macOS命令行创建Android模拟器
    macOS下不安装AndroidStudio使用VSCode来开发Flutter应用使用命令行创建和管理Android模拟器设备avdmanageravdmanager 是一种命令 ... [详细]
  • 资源:吊炸天!74款APP完整源码!android界面中点击输入框时弹出输入法如果输入框在底部会出现输入法遮挡输入内容的问题解决办法设置activity的windowsoftinpu ... [详细]
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社区 版权所有