WKWebview保存图片到相册并弹窗提示
2019-04-23 本文已影响0人
DeCori
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;
}