zoukankan      html  css  js  c++  java
  • iOS UIWebview 长按图片,保存到本地相册

    我们所要解决的问题如题目所示:ios中,长按Webview中的图片,将图片保存到本地相册。

    解决方案:对load的html网页,执行js注入,通过在webview中执行js代码,来响应点击事件,通过js代码来模拟长按事件。发现图片的位置,获得图片的url链接,通过此链接获得图片,将此图片保存到本地相册。

    js注入代码:

    static NSString* const kTouchJavaScriptString=
    @"document.ontouchstart=function(event){
    x=event.targetTouches[0].clientX;
    y=event.targetTouches[0].clientY;
    document.location="myweb:touch:start:"+x+":"+y;};
    document.ontouchmove=function(event){
    x=event.targetTouches[0].clientX;
    y=event.targetTouches[0].clientY;
    document.location="myweb:touch:move:"+x+":"+y;};
    document.ontouchcancel=function(event){
    document.location="myweb:touch:cancel";};
    document.ontouchend=function(event){
    document.location="myweb:touch:end";};";

    这段js的作用主要用于响应touch事件,以及获得点击的坐标位置,
    在webview加载完成之后,将此段js代码注入,源码如下:
    -(void)webViewDidFinishLoad:(UIWebView *)webView {
        [self.getWebView stringByEvaluatingJavaScriptFromString:kTouchJavaScriptString];
    }

    js执行代码:
    -(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)_request navigationType:(UIWebViewNavigationType)navigationType {
        NSString *requestString = [_request URL] absoluteString];
        NSArray *components = [requestString componentsSeparatedByString:@":"];
        if ([components count] > 1 && [(NSString *)[components objectAtIndex:0]
                                       isEqualToString:@"myweb"]) {
            if([(NSString *)[components objectAtIndex:1] isEqualToString:@"touch"])
            {
                //NSLog(@"you are touching!");
                //NSTimeInterval delaytime = Delaytime;
                if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"start"])
                {
                    /*
                     @需延时判断是否响应页面内的js...
                     */
                    _gesState = GESTURE_STATE_START;
                    NSLog(@"touch start!");
                    
                    float ptX = [components objectAtIndex:3]floatValue];
                    float ptY = [components objectAtIndex:4]floatValue];
                    NSLog(@"touch point (%f, %f)", ptX, ptY);
                    
                    NSString *js = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).tagName", ptX, ptY];
                    NSString * tagName = [self.getWebView stringByEvaluatingJavaScriptFromString:js];
                    _imgURL = nil;
                    if ([tagName isEqualToString:@"IMG"]) {
                        _imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", ptX, ptY];
                    }
                    if (_imgURL) {
                        _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(handleLongTouch) userInfo:nil repeats:NO];
                    }
                }
                else if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"move"])
                {
                    //**如果touch动作是滑动,则取消hanleLongTouch动作**//
                    _gesState = GESTURE_STATE_MOVE;
                    NSLog(@"you are move");
                    }
                }
                else if ([(NSString*)[components objectAtIndex:2]isEqualToString:@"end"]) {
                    [_timer invalidate];
                    _timer = nil;
                    _gesState = GESTURE_STATE_END;
                    NSLog(@"touch end");
                }
            }
            return NO;
        }
        return YES;
    }

    如果点击的是图片,并且按住的时间超过1s,执行handleLongTouch函数,处理图片的保存操作。
    - (void)handleLongTouch {
        NSLog(@"%@", _imgURL);
        if (_imgURL && _gesState == GESTURE_STATE_START) {
            UIActionSheet* sheet = [UIActionSheet alloc]initWithTitle:nil delegate:self cancelButtonTitle:@"取消" destructiveButtonTitle:nil otherButtonTitles:@"保存图片", nil];
            sheet.cancelButtonIndex = sheet.numberOfButtons - 1;
            [sheet showInView:[UIApplication sharedApplication].keyWindow];
        }
    }

    - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
        if (actionSheet.numberOfButtons - 1 == buttonIndex) {
            return;
        }
        NSString* title = [actionSheet buttonTitleAtIndex:buttonIndex];
        if ([title isEqualToString:@"保存图片"]) {
            if (_imgURL) {
                NSLog(@"imgurl = %@", _imgURL);
            }
            NSString *urlToSave = [self.getWebView stringByEvaluatingJavaScriptFromString:_imgURL];
            NSLog(@"image url=%@", urlToSave);
            
            NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlToSave];
            UIImage* image = [UIImage imageWithData:data];
            
            //UIImageWriteToSavedPhotosAlbum(image, nil, nil,nil);
            UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
        }
    }

    - (void)image:(UIImage *)image didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo
    {
        if (error){
            NSLog(@"Error");
            [self showAlert:SNS_IMAGE_HINT_SAVE_FAILE];
        }else {
            NSLog(@"OK");
            [self showAlert:SNS_IMAGE_HINT_SAVE_SUCCE];
        }
    }

  • 相关阅读:
    docker log
    byte转String防止乱码
    SQL索引
    Redis 总结精讲
    如何保证消息队列是高可用的
    消息中间件(一)MQ详解及四大MQ比较
    @Bean和@Componet区别
    理解Spring的AOP和Ioc/DI就这么简单
    SpringBoot 基础
    《Linux 鸟哥私房菜》 第6章 Linux的文件权限与目录配置
  • 原文地址:https://www.cnblogs.com/HMJ-29/p/5407619.html
Copyright © 2011-2022 走看看