UIWebView长按图片生成保存菜单
参考:
http://www.icab.de/blog/2010/07/11/customize-the-contextual-menu-of-uiwebview/
http://www.icab.de/blog/2011/10/17/elementfrompoint-under-ios-5/comment-page-1/#comment-30184
自定义UILongPressGestureRecognizer
创建 UnpreventableUILongPressGestureRecognizer.h
#import <Foundation/Foundation.h>
@interface UnpreventableUILongPressGestureRecognizer : UILongPressGestureRecognizer {
}
@end
UnpreventableUILongPressGestureRecognizer.m
#import "UnpreventableUILongPressGestureRecognizer.h"
@implementation UnpreventableUILongPressGestureRecognizer
- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer {
return NO;
}
@end
UIWebview页面给webview添加手势 ViewController.m:
UnpreventableUILongPressGestureRecognizer *longPressRecognizer = [[UnpreventableUILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
longPressRecognizer.allowableMovement = 20;
longPressRecognizer.minimumPressDuration = 1.0f;
[webview addGestureRecognizer:longPressRecognizer];
ViewController.m 处理手势:
-(void)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
CGPoint pt = [gestureRecognizer locationInView:self.webview];
// convert point from view to HTML coordinate system
// 뷰의 포인트 위치를 HTML 좌표계로 변경한다.
CGSize viewSize = [webview frame].size;
CGSize windowSize = [webview windowSize];
CGFloat f = windowSize.width / viewSize.width;
if ([[[UIDevice currentDevice] systemVersion] doubleValue] >= 5.0) {
pt.x = pt.x * f;
pt.y = pt.y * f;
} else {
// On iOS 4 and previous, document.elementFromPoint is not taking
// offset into account, we have to handle it
CGPoint offset = [webview scrollOffset];
pt.x = pt.x * f + offset.x;
pt.y = pt.y * f + offset.y;
}
[self openContextualMenuAt:pt];
}
}
创建分类 WebViewAdditions.h
#import <foundation foundation.h="">
@interface UIWebView(WebViewAdditions)
- (CGSize)windowSize;
- (CGPoint)scrollOffset;
@end
</foundation>
WebViewAdditions.m
#import "WebViewAdditions.h"
@implementation UIWebView(WebViewAdditions)
- (CGSize)windowSize
{
CGSize size;
size.width = [[self stringByEvaluatingJavaScriptFromString:@"window.innerWidth"] integerValue];
size.height = [[self stringByEvaluatingJavaScriptFromString:@"window.innerHeight"] integerValue];
return size;
}
- (CGPoint)scrollOffset
{
CGPoint pt;
pt.x = [[self stringByEvaluatingJavaScriptFromString:@"window.pageXOffset"] integerValue];
pt.y = [[self stringByEvaluatingJavaScriptFromString:@"window.pageYOffset"] integerValue];
return pt;
}
@end
弹出菜单 ViewController.m
- (void)openContextualMenuAt:(CGPoint)pt{
// Load the JavaScript code from the Resources and inject it into the web page
NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"Naving" ofType:@"bundle"]];
NSString *path = [bundle pathForResource:@"JSTools" ofType:@"js"];
NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[webview stringByEvaluatingJavaScriptFromString:jsCode];
// get the Tags at the touch location
NSString *tags = [webview stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"MyAppGetHTMLElementsAtPoint(%i,%i);",(NSInteger)pt.x,(NSInteger)pt.y]];
NSString *tagsHREF = [webview stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"MyAppGetLinkHREFAtPoint(%i,%i);",(NSInteger)pt.x,(NSInteger)pt.y]];
NSString *tagsSRC = [webview stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:@"MyAppGetLinkSRCAtPoint(%i,%i);",(NSInteger)pt.x,(NSInteger)pt.y]];
NSLog(@"tags : %@",tags);
NSLog(@"href : %@",tagsHREF);
NSLog(@"src : %@",tagsSRC);
if (!_actionActionSheet) {
_actionActionSheet = nil;
}
_actionActionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
selectedLinkURL = @"";
selectedImageURL = @"";
// If an image was touched, add image-related buttons.
if ([tags rangeOfString:@",IMG,"].location != NSNotFound) {
selectedImageURL = tagsSRC;
if (_actionActionSheet.title == nil) {
_actionActionSheet.title = tagsSRC;
}
[_actionActionSheet addButtonWithTitle:@"Save Image"];
[_actionActionSheet addButtonWithTitle:@"Copy Image"];
}
// If a link is pressed add image buttons.
if ([tags rangeOfString:@",A,"].location != NSNotFound){
selectedLinkURL = tagsHREF;
_actionActionSheet.title = tagsHREF;
[_actionActionSheet addButtonWithTitle:@"Open Link"];
[_actionActionSheet addButtonWithTitle:@"Copy Link"];
}
if (_actionActionSheet.numberOfButtons > 0) {
[_actionActionSheet addButtonWithTitle:@"Cancel"];
_actionActionSheet.cancelButtonIndex = (_actionActionSheet.numberOfButtons-1);
[_actionActionSheet showInView:webview];
}
}
工具文件 JSTools.js
function MyAppGetHTMLElementsAtPoint(x,y) {
var tags = ",";
var e = document.elementFromPoint(x,y);
while (e) {
if (e.tagName) {
tags += e.tagName + ',';
}
e = e.parentNode;
}
return tags;
}
function MyAppGetLinkSRCAtPoint(x,y) {
var tags = "";
var e = document.elementFromPoint(x,y);
while (e) {
if (e.src) {
tags += e.src;
break;
}
e = e.parentNode;
}
return tags;
}
function MyAppGetLinkHREFAtPoint(x,y) {
var tags = "";
var e = document.elementFromPoint(x,y);
while (e) {
if (e.href) {
tags += e.href;
break;
}
e = e.parentNode;
}
return tags;
}
ViewController.m 处理ActionSheet事件
#pragma UIActionSheetDelegate
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:@"Open Link"]){
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:selectedLinkURL]]];
}
else if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:@"Copy Link"]){
[[UIPasteboard generalPasteboard] setString:selectedLinkURL];
}
else if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:@"Copy Image"]){
[[UIPasteboard generalPasteboard] setString:selectedImageURL];
}
else if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:@"Save Image"]){
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(saveImageURL:) object:selectedImageURL];
[queue addOperation:operation];
//[operation release];
}
}
-(void)saveImageURL:(NSString*)url{
[self performSelectorOnMainThread:@selector(showStartSaveAlert)
withObject:nil
waitUntilDone:YES];
UIImageWriteToSavedPhotosAlbum([UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:url]]], nil, nil, nil);
[self performSelectorOnMainThread:@selector(showFinishedSaveAlert)
withObject:nil
waitUntilDone:YES];
}