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

目录
相关文章
|
8月前
|
Web App开发 缓存 JavaScript
WKWebView相对UIWebView的优劣势
WKWebView相对UIWebView的优劣势
65 1
|
JavaScript 前端开发 Android开发
iOS 自动适配的 WebView 封装 (下)
iOS 自动适配的 WebView 封装 (下)
196 0
iOS 自动适配的 WebView 封装 (下)
|
缓存 JavaScript 前端开发
iOS 自动适配的 WebView 封装 (上)
iOS 自动适配的 WebView 封装 (上)
855 0
iOS 自动适配的 WebView 封装 (上)
|
存储 iOS开发
iOS wkwebview嵌入优酷视频,显示“请允许cookie存储”解决方法
iOS wkwebview嵌入优酷视频,显示“请允许cookie存储”解决方法
621 0
|
JavaScript 安全 Java
WebView开源库终极方案
目录介绍 01.前沿说明 1.1 案例展示效果 1.2 该库功能和优势 1.3 相关类介绍说明 1.4 WebView知识点 02.如何使用 2.1 如何引入 2.2 最简单使用 2.3 常用api 2.
2693 0
|
缓存 安全 API
X5webview去掉分享功能和缓存功能
x5webview比原生的webview适配更好,加载更快,对音视频的兼容性更好,具备独特的优势 1) 速度快:相比系统webview的网页打开速度有30+%的提升; 2) 省流量:使用云端优化技术使流量节省20+%; 3) 更安全:安全问题可以在24小时内修复; 4) 更稳定:经过亿级用户的使用考验,CRASH率低于0.
2477 0
|
Android开发 数据格式 XML
Android8.0 适配解决页面跳转过程出现短暂黑屏的问题
      小菜在适配 Android8.0 过程中,遇到很多问题,有很多很常见的问题,今天来整理一下页面跳转时黑屏的问题。 问题猜测 猜测一:       显示 Activity 页面之前会优先开启一个 Starting Window(Preview Window),等待 Activity 加载完成之后显示 UI 界面,猜测在这个等待过程中可能会出现页面跳转时的短暂黑屏。
3244 0
|
缓存 移动开发 JavaScript
weex 在 iOS 上如何实现常见的网络缓存
weex 旨在兼顾web动态性与native的用户体验,如果想将两者的优势最大化,那么缓存就显得格外重要,本文介绍如何利用缓存,实现weex页面迅速打开,甚至“秒开”的效果。
3157 0