WKWebview保存图片到相册并弹窗提示

wk本身自带长按保存图片功能(保存完不弹窗),产品要求从web保存图片到相册,保存完还要弹窗提示,没办法只能自己写了~~

1.禁用自身选中效果

#pragma mark - 结束
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
    // 禁用选中效果(长安手势等)
    [self.wv evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none'" completionHandler:nil];
    [self.wv evaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none'" completionHandler:nil];
}

2.添加长按手势

// 添加长按手势
    UILongPressGestureRecognizer *lp = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
    lp.minimumPressDuration = 1;
    lp.delegate = self;
    [wk addGestureRecognizer:lp];

3.保存图片

根据坐标获取html元素document.elementFromPoint(%f, %f)这句js就是获取这个元素的代码,但是直接注入这个代码返回值是空,必须注入如:
(1)获取该元素class标签对应的值document.elementFromPoint(%f, %f).className
(2)获取该元素标签值document.elementFromPoint(%f, %f).tagName

#pragma mark - 保存图片
/*通过点击(或者长按)获取元素,获取到元素时候取出tagName,如果tagName是IMG,那就再取src, 这就是网络图片的地址了,用此方法可以取出网页上任意图片的地址, 根据图片地址保存图片到相册*/
- (void)handleLongPress:(UILongPressGestureRecognizer *)sender{
    if (sender.state != UIGestureRecognizerStateBegan) {
        return;
    }
    CGPoint touchPoint = [sender locationInView:self.wv];
    CGFloat ptX, ptY;
    ptX = touchPoint.x;
    ptY = touchPoint.y;
    // 获取长按位置对应的图片url的JS代码
    [_wv evaluateJavaScript:[NSString stringWithFormat:@"document.elementFromPoint(%f, %f).tagName", ptX, ptY] completionHandler:^(id _Nullable response, NSError * _Nullable error) {
        NSString * tagName = response;
        NSLog(@"tagName %@", tagName);
        if ([tagName isEqualToString:@"IMG"]) {
            [self->_wv evaluateJavaScript:[NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", ptX, ptY] completionHandler:^(id _Nullable response, NSError * _Nullable error) {
                //图片地址
                NSString * imgUrl = response;
                if (imgUrl) {
                    UIImage *img = [self downloadImage:imgUrl];
                    if (!img) {
                        NSLog(@"读取图片失败");
                        return;
                    }
                    FSActionSheet *actionSheet = [[FSActionSheet alloc] initWithTitle:nil
                                                                             delegate:nil
                                                                    cancelButtonTitle:@"取消"
                                                               highlightedButtonTitle:nil
                                                                    otherButtonTitles:@[@"保存图片"]];
                    __weak typeof(self) weakSelf = self;
                    // 展示并绑定选择回调
                    [actionSheet showWithSelectedCompletion:^(NSInteger selectedIndex) {
                        if (selectedIndex==0) {
                            // 保存图片到相册中
                            UIImageWriteToSavedPhotosAlbum(img,weakSelf, @selector(image:didFinishSavingWithError:contextInfo:),nil);
                        }
                    }];
                }
            }];
        }
    }];
}

- (UIImage *)downloadImage:(NSString *)urlString {
    NSURL *url = [NSURL URLWithString: urlString];
    SDWebImageManager *manager = [SDWebImageManager sharedManager];
    UIImage *img;
    if ([manager diskImageExistsForURL:url]) {
        img = [[manager imageCache] imageFromDiskCacheForKey:url.absoluteString];
    } else {
        //从网络下载图片
        NSData *data = [NSData dataWithContentsOfURL:url];
        img = [UIImage imageWithData:data];
    }
    if (!img) {
        NSLog(@"读取图片失败");
        return nil;
    }
    return img;
}

//保存图片完成之后的回调
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
    // Was there an error?
    if (error != NULL) {
        // Show error message…
        [SVProgressHUD showErrorWithStatus:@"图片保存失败"];
    }else // No errors
    { // Show message image successfully saved
        [SVProgressHUD showSuccessWithStatus:@"图片保存成功"];
    }
}

4.若长按手势无反应添加如下代码

/*这个协议是在处理手势时,本手势是否和其他手势同时被识别,返回YES就是可以被同时识别的意思。
 PS:这个代理方法如果返回NO,可以保证不同时识别别的手势;但是返回YES不能保证一定可以同时识别到别手势,因为别的手势的代理处理方法可能是返回NO的。
 */
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

参考文章

你可能感兴趣的:(WKWebview保存图片到相册并弹窗提示)