選擇放這張效果圖的時候很是忐忑啊,不知道會不會被和諧掉。
拿到需求之后分析了一下,其實主要功能點就是如何才能通過手指按壓位置獲取到相應的圖片資源。是不是很抓狂,如果考慮到設備適配,誰知道手指按在什么地方了。
直接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),不然我是看不到的,而且有些網站在轉載的時候連排版都不會檢查一下,真的很讓人頭疼。
如果你覺得這篇文章多多少少幫助到了你一些,打賞倒是不用,點個關注加喜歡吧,謝謝大家的認可。