美文网首页
如何将UIWebView里面的图片保存到相册中

如何将UIWebView里面的图片保存到相册中

作者: Crazy2015 | 来源:发表于2017-08-14 14:35 被阅读50次

    不知道各位对于这个需求要如何解决?
    可能有些人会想到js与原生交互,js监听图片点击事件,然后将图片的url传递给原生App端,然后原生App将图片保存到相册,这样子麻烦吗?超麻烦。
    (1)js监听图片长按事件;
    (2)js将图片url传递给原生;
    (3)原生通过图片的url生成UIImage;
    (4)保存UIImage到系统相册;

    步骤如下:

    需要注入的js代码:
    @"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\";};";
    
    其中
    touchstart,
    touchmove,
    touchend
    用来捕获元素的触摸事件。
    

    第一步:需要将js代码注入到交互的页面中。

    -(void)webViewDidFinishLoad:(UIWebView *)webView {
        [self.webView stringByEvaluatingJavaScriptFromString:kTouchJavaScriptString];
    }
    

    第二步:
    用js来监听触摸图片长按事件,然后在webview的delegate方法里截取resquest就行了:
    用到如下的代理方法:

    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    

    然后,根据触摸点x,y的位置,并且通过js
    document.elementFromPoint(%f, %f).tagName获取标签,
    然后判断是不是图片,
    如果是图片的话,提取图片的src
    document.elementFromPoint(%f, %f).src

    第三步:
    将图片的URL经过转换成原生OC可以用的URL
    // _imgURL<===>document.elementFromPoint(%f, %f).src
    NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:_imgURL];,
    然后生成UIImage

    第四步:保存UIImage到系统相册

    掘金上面的另一种解决方案:
    https://juejin.im/post/5981a278f265da3e260954b1
    我自己如下的解决方案:

    代码:

    #import "ViewController.h"
    #import <WebKit/WebKit.h>
    #import "WKDelegateController.h"
    
    
    typedef enum : NSUInteger {
        GESTURE_STATE_START,
        GESTURE_STATE_MOVE,
        GESTURE_STATE_END,
    } GESTURE_STATE;
    
    @interface ViewController()<UIWebViewDelegate>
    @property (nonatomic, strong) UIWebView *webView;
    @property (nonatomic, strong) NSString *imgURL;
    @property (nonatomic, strong) NSTimer *timer;
    @property (nonatomic, assign) GESTURE_STATE gesState;
    
    @end
    
    
    
    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\";};";
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
        self.webView.delegate = self;
        [self.view addSubview:self.webView];
        
        NSString *urlStr = @"http://politics.people.com.cn/n1/2017/0810/c14562-29463365.html";
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]];
        [self.webView loadRequest:request];
    }
    
    -(void)webViewDidFinishLoad:(UIWebView *)webView {
        [self.webView stringByEvaluatingJavaScriptFromString:kTouchJavaScriptString];
    }
    
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
        
        NSString *requestString = [[request URL] absoluteString];
        NSLog(@"%s", __func__);
        NSLog(@"requestString = %@", requestString);
        NSLog(@"currentThread = %@", [NSThread currentThread]);
        NSArray *components = [requestString componentsSeparatedByString:@":"];
        if ([components count] > 1 && [(NSString *)[components objectAtIndex:0]
                                       isEqualToString:@"myweb"]) {
            if([(NSString *)[components objectAtIndex:1] isEqualToString:@"touch"]) {
                if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"start"]) {
                    
                    _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.webView stringByEvaluatingJavaScriptFromString:js];
                    _imgURL = nil;
                    if ([tagName isEqualToString:@"IMG"]) {
                        _imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", ptX, ptY];
                    }
                    if (_imgURL) {
                        _timer = [NSTimer scheduledTimerWithTimeInterval:2 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;
    }
    
    - (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.webView stringByEvaluatingJavaScriptFromString:_imgURL];
            NSLog(@"image url=%@", urlToSave);
            
            NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlToSave]];
            UIImage* image = [UIImage imageWithData:data];
                                                          
            
          UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
        }
    }
    
    - (void) dealloc {
        if(self.webView){
            [self.webView stopLoading];
            self.webView.delegate = nil;
        }
    }
    
    - (void)image:(UIImage *)image didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo{
        if (error){
            NSLog(@"Error");
    //      [self showAlert:@"保存失败"];
        }else {
            NSLog(@"OK");
    //      [self showAlert:@"保存成功"];
        }
    }
    
    

    相关文章

      网友评论

          本文标题:如何将UIWebView里面的图片保存到相册中

          本文链接:https://www.haomeiwen.com/subject/pyglrxtx.html