选择放这张效果图的时候很是忐忑啊,不知道会不会被和谐掉。
拿到需求之后分析了一下,其实主要功能点就是如何才能通过手指按压位置获取到相应的图片资源。是不是很抓狂,如果考虑到设备适配,谁知道手指按在什么地方了。
直接google查到了下面的这两行代码,然后跑到H5大哥那请教,给我实际演示了一下,发现能够完美解决上面的问题。
NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", touchPoint.x, touchPoint.y];
NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:imgURL];
整篇文章的精髓就全在上面的那两行代码里了,接下来我就把完整的实现代码放上来。
首先是给UiWebView加一个长按手势。
UILongPressGestureRecognizer* longPressed = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressed:)];
longPressed.delegate = self;
[self.webView addGestureRecognizer:longPressed];
接着在手势响应方法里面实现相应的获取图片地址的方法,并弹出SheetView。这里需要注意的是一定要判断手势的state属性,想知道后果的同学可以注掉判断代码自己尝试一下。另外就是如果手指长按位置是非图片的话,urlToSave是一个nil值。
- (void)longPressed:(UILongPressGestureRecognizer*)recognizer
{
if (recognizer.state != UIGestureRecognizerStateBegan) {
return;
}
CGPoint touchPoint = [recognizer locationInView:self.webView];
NSString *imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", touchPoint.x, touchPoint.y];
NSString *urlToSave = [self.webView stringByEvaluatingJavaScriptFromString:imgURL];
if (urlToSave.length == 0) {
return;
}
[self showImageOptionsWithUrl:urlToSave];
}
接下来的方法是调用一个自己封装好的SheetVIew,大家完全可以跳过,列出来只是为了不破坏代码的连贯性。
- (void)showImageOptionsWithUrl:(NSString *)imageUrl
{
RAActionCustomButton *saveBtn = [[RAActionCustomButton alloc] init];
saveBtn.type = kRAActionCustomButtonTypeSheetWhite;
[saveBtn setTitle:@"保存图片" forState:UIControlStateNormal];
saveBtn.touchUpInsideBlock = ^(RAActionCustomButton *btn){
[self saveImageToDiskWithUrl:imageUrl];
};
RAActionCustomButton *cancelBtn = [[RAActionCustomButton alloc] init];
cancelBtn.type = kRAActionCustomButtonTypeSheetWhite;
[cancelBtn setTitle:@"取消" forState:UIControlStateNormal];
cancelBtn.touchUpInsideBlock = ^(RAActionCustomButton *btn){
};
RAActionSheet *sheet = [[RAActionSheet alloc] init];
sheet.actionBtns = @[ saveBtn, cancelBtn];
[sheet show];
}
最后就是请求图片并保存到相册的方法。这里需要注意一下cachePolicy这个参数,当前选择的参数含义是只有在cache中不存在data时才从原始地址下载。在实现过程中大家可以根据实际的功能需求来选择不同的参数。
- (void)saveImageToDiskWithUrl:(NSString *)imageUrl
{
NSURL *url = [NSURL URLWithString:imageUrl];
NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue new]];
NSURLRequest *imgRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30.0];
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:imgRequest completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
return ;
}
NSData * imageData = [NSData dataWithContentsOfURL:location];
dispatch_async(dispatch_get_main_queue(), ^{
UIImage * image = [UIImage imageWithData:imageData];
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
});
}];
[task resume];
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
if (error) {
[[RAProgressHUD sharedHUD] showErrorWithMessage:@"保存失败"];
}else{
[[RAProgressHUD sharedHUD] showSuccessWithMessage:@"保存成功"];
}
}
功能实现代码已经完整的贴出来了,接下来聊一些文章之外的事情。首先感谢大家对我的支持,尤其是上一篇文章iOS雷达图 iOS RadarChart实现,不过让人哭笑不得的是大家要demo的方式有一种向老司机要种子的既视感😂。没有及时放上demo是我偷懒了,我会马上更新的。另外要特别感谢给我打赏的那位,感谢你对我的认可,真是让我受宠若惊,我的文章竟然值钱咧。
再有就是我的文章都是在简书上面写的,所以大家有什么问题还是最好到原文章下面来讨论(尤其是要demo),不然我是看不到的,而且有些网站在转载的时候连排版都不会检查一下,真的很让人头疼。
如果你觉得这篇文章多多少少帮助到了你一些,打赏倒是不用,点个关注加喜欢吧,谢谢大家的认可。