我們所要解決的問題如題目所示:ios中,長按Webview中的圖片,將圖片保存到本地相冊。
解決方案:對load的html網頁,執行js注入,通過在webview中執行js代碼,來響應點擊事件,通過js代碼來模擬長按事件。發現圖片的位置,獲得圖片的url鏈接,通過此鏈接獲得圖片,將此圖片保存到本地相冊。
js注入代碼:
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\";};";
這段js的作用主要用於響應touch事件,以及獲得點擊的坐標位置,
在webview加載完成之后,將此段js代碼注入,源碼如下:
-(void)webViewDidFinishLoad:(UIWebView *)webView {
[self.getWebView stringByEvaluatingJavaScriptFromString:kTouchJavaScriptString];
}
js執行代碼:
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)_request navigationType:(UIWebViewNavigationType)navigationType {
NSString *requestString = [_request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:@":"];
if ([components count] > 1 && [(NSString *)[components objectAtIndex:0]
isEqualToString:@"myweb"]) {
if([(NSString *)[components objectAtIndex:1] isEqualToString:@"touch"])
{
//NSLog(@"you are touching!");
//NSTimeInterval delaytime = Delaytime;
if ([(NSString *)[components objectAtIndex:2] isEqualToString:@"start"])
{
/*
@需延時判斷是否響應頁面內的js...
*/
_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.getWebView stringByEvaluatingJavaScriptFromString:js];
_imgURL = nil;
if ([tagName isEqualToString:@"IMG"]) {
_imgURL = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", ptX, ptY];
}
if (_imgURL) {
_timer = [NSTimer scheduledTimerWithTimeInterval:1 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;
}
如果點擊的是圖片,並且按住的時間超過1s,執行handleLongTouch函數,處理圖片的保存操作。
- (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.getWebView stringByEvaluatingJavaScriptFromString:_imgURL];
NSLog(@"image url=%@", urlToSave);
NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlToSave];
UIImage* image = [UIImage imageWithData:data];
//UIImageWriteToSavedPhotosAlbum(image, nil, nil,nil);
UIImageWriteToSavedPhotosAlbum(image, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
}
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError*)error contextInfo:(void*)contextInfo
{
if (error){
NSLog(@"Error");
[self showAlert:SNS_IMAGE_HINT_SAVE_FAILE];
}else {
NSLog(@"OK");
[self showAlert:SNS_IMAGE_HINT_SAVE_SUCCE];
}
}