WKWebView之长按手势

WKWebView之长按手势


PAWebView
PAWebView 之 cookie 管理与同步;
PAWebView 之长按手势;
PAWebView 之POST请求;

一、引言

   在hybird app 里,长按手势的运用非常广泛,特别是DOM的运用与native和JS交互的实现,使得Navitve对HTML的操作无所不能。如查看、屏蔽、替换、复制、下载、识别二维码和分享等功能都可以轻松实现,那么长按手势更是可以实现让用户便捷的一些功能。

二、WKWebView长按手势

1. WebView触摸事件

   绝大多WebView层的触摸事件暂时还不能由Native直接拦截更改,目前Native可以监听长按、点击等一些手势状态,但是如果需要禁止或改变这些事件或属性,我们可以通过向H5注入JS代码来实现,iOS WebKit 框架下的CSS扩展也可以实现部分功能

2.关闭网页的长按手势

   利用WebKit CSS 扩展 webkitTouchCallout属性实现。
document.documentElement.style.webkitTouchCallout=’none’;

错误用法:
   一些开发者在webViewDidFinishLoad 代理中实现该方法。实际上,经过测试,这种调用方法不能完全禁止WebView端的长按手势,估计是网页加载过慢时方法注入延时导致WebView端长按依然有效。


- (void)webViewDidFinishLoad:(UIWebView *)webView {
    // Disable callout
    [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];

正确用法:
   在初始化WebView时使用WKUserContentController对象注入禁止长按的方法。


NSMutableString *javascript = [NSMutableString string];
[javascript appendString:@"document.documentElement.style.webkitTouchCallout='none';"];//禁止长按
WKUserScript *noneSelectScript = [[WKUserScript alloc] initWithSource:javascript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
[_config.userContentController addUserScript:noneSelectScript];

3.WebView添加手势
  • webview添加事件

UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(startLongPress:)];
longPress.delegate = self;

longPress.minimumPressDuration = 0.4f;
longPress.numberOfTouchesRequired = 1;
longPress.cancelsTouchesInView = YES;
[self addGestureRecognizer:longPress];

  • 实现UILongPressGestureRecognizer代理,精确处理手势动作

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    NSLog(@"%@",otherGestureRecognizer.class);

    if ([otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
        //只有当手势为长按手势时反馈,飞长按手势将阻止。
        return YES;
    }else{
        return NO;
    }
}

  • 长按反馈

- (void)startLongPress:(UILongPressGestureRecognizer *)pressSender
{
    if(pressSender.state == UIGestureRecognizerStateBegan){

       //实现相关功能
        [self detectInWebView:pressSender];
        NSLog(@"1. 开始长按手势");

    }else if(pressSender.state == UIGestureRecognizerStateEnded){

        //可以添加你长按手势执行的方法,不过是在手指松开后执行
        NSLog(@"2. 结束长按手势");

    }else if(pressSender.state == UIGestureRecognizerStateChanged){

        //在手指点下去一直不松开的状态执行
        NSLog(@"3. 长按手势改变");
    }
}

4.解决长按结束时a对应URL超链接触发跳转问题

   查阅了很多国内技术论坛资料,这个问题普遍都困扰着开发者。我研究了一下系统自带的长按手势的功能,当长按触发时,WebView 的手势响应事件被全部终止,然后弹出UIMenuController视图,UC也是类似的处理。目前不清楚怎么实现,知道的伙伴交流一下。但是可以使用其他方法来代替。

方法一:
   以弹出的视图作为长按触发成功的标志,视图弹出,长按触发,然后在WKWebView的代理方法 decidePolicyForNavigationAction 里拦截网页跳转;视图消失,长按完毕。方法虽笨,但是还是很实用,目前的很多开发者都采用这种方式实现。


- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:
(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{

    if (_longpress) {
        _longpress = NO;
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }
}

方法二
   借助系统自带的长按响应机制忽略单击事件。去掉document.documentElement.style.webkitTouchCallout=’none’;设置。
移除UIMenuController清除系统的长按响应形式。弹出我们自定义的弹框形式。

移除视图的方法


for (UIView* subview in self.webViewWK.scrollView.subviews) 
{         
   if ([subview isKindOfClass:NSClassFromString(@"WKContentViewMinusAccessoryView")])         
  {             
       for (UIGestureRecognizer* longPress in subview.gestureRecognizers) 
     {                     
         [subview removeGestureRecognizer:longPress];                          
       }             
    }        
}    

5.抓取/更改网页元素属性

   抓取H5主要使用了WKWebView的JS代码注入和DOM的H5文件操作来实现。
   JS代码注入方法。届时除了了解JS代码注入的实现,还需要了解JavaScript/jQuery,HTML,DOM的相关知识。

相关教程:
JS:http://www.w3school.com.cn/js/js_library_jquery.asp
HTML:http://www.w3school.com.cn/html5/index.asp
DOM:http://www.w3school.com.cn/htmldom/dom_intro.asp

WKWebView框架注入代码API


[self evaluateJavaScript:JSFunction completionHandler:^(id _Nullable href, NSError * _Nullable error)
{}];

相关JS方法


1.获取点击位置的url
function JSSearchHref(x,y) {
                        var e = document.elementFromPoint(x, y);
                        while(e){
                            if(e.href){
                            return e.href;
                        }
                        e = e.parentElement;
                        }
                        return e.href;
                  }
2.获取标题

function JSSearchText(x,y) {
                  return document.elementFromPoint(x, y).innerText;
                    }
3.获取图片

function JSSearchImage(x,y) {
                        return document.elementFromPoint(x, y).src;
                    }
4.获取HTML所有的图片

function JSSearchAllImage(){
         var img = [];
         for(var i=0;i<$('img').length;i++){
              if(parseInt($('img').eq(i).css('width'))>60){ 
                 //获取所有符合放大要求的图片,将图片路径(src)获取
                 img[i] = $('img').eq(i).attr('src');
               }
             }
         var img_info = {};
         img_info.list = img; //保存所有图片的url
         return img;
}
5.获取web page的宽
document.getElementById('content').offsetWidth
6.获取web page的长
document.getElementById('content').offsetHeight
等等。。

JS注入使用例子



/** 获取HTML所有的图片 */
NSString* const JSSearchAllImageFromHtml =
           @"function JSSearchAllImage(){\
                var img = [];\
                for(var i=0;i<$('img').length;i++){\
                   if(parseInt($('img').eq(i).css('width'))>60){ \
                       //获取所有符合放大要求的图片,将图片路径(src)获取
                       img[i] = $('img').eq(i).attr('src');\
                     }\
               }\
               var img_info = {};\
               img_info.list = img;\ //保存所有图片的url
               return img;\
           };

//注入JS方法
NSString *hrefJS = JSSearchAllImageFromHtml;
[self evaluateJavaScript:hrefJS completionHandler:nil];

//调用JS方法
NSString *hrefFunc = [NSString stringWithFormat:@"JSSearchAllImage();"];
[self evaluateJavaScript:hrefFunc completionHandler:^(id _Nullable image, NSError * _Nullable error)
{
      NSArray *imageArray = [self sortImageFromArray:image];
      NSLog(@"%@",imageArray);
}];


6.具体功能的实现

   PAWebView里面具体实现了该功能。具体代码和功能的实现请查看 github :https://github.com/llyouss/PAWeView

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值