Iphone UIWebView-在<;img>;标签
是我还是在UIWebView中禁用了Iphone UIWebView-在<;img>;标签,iphone,ios,ios4,uiwebview,Iphone,Ios,Ios4,Uiwebview,是我还是在UIWebView中禁用了标记上的操作表?例如,在Safari中,当您想在本地保存图像时,您可以按住图像以显示操作表。但它在我的自定义UIWebView中不起作用。我的意思是,它仍然适用于标记,也就是说,当我触摸并按住html链接时,会显示一个操作表。但不适用于标记 我尝试过在css中放置img{-webkit touch callout:inherit;},但没有成功。另一方面,当我双击并按住图像时,会显示一个复制气球 所以问题是,标记的默认操作表标注是否已为UIWebView禁用?
标记上的操作表?例如,在Safari中,当您想在本地保存图像时,您可以按住图像以显示操作表。但它在我的自定义UIWebView中不起作用。我的意思是,它仍然适用于
标记,也就是说,当我触摸并按住html链接时,会显示一个操作表。但不适用于
标记
我尝试过在css中放置img{-webkit touch callout:inherit;}
,但没有成功。另一方面,当我双击并按住图像时,会显示一个复制气球
所以问题是,
标记的默认操作表标注是否已为UIWebView禁用?那么,有没有办法重新启用它?我在谷歌上搜索了很多关于如何在UIWebView中禁用它的问题,所以只有我没有看到弹出窗口吗
提前谢谢 是的,苹果已经在UIWebView中禁用了此功能(以及其他功能),并将其保留为仅用于Safari 但是,通过扩展本教程,您可以自己重新创建 完成本教程后,您将需要添加一些额外的,以便您可以实际保存图像(本教程没有介绍)。 我在0.3秒后添加了一个名为@“tapAndHoldShortNotification”的额外通知,该通知调用了一个只包含禁用调出代码的方法(为了防止在页面仍在加载时弹出默认菜单和您自己的菜单,进行了一点bug修复) 此外,为了检测图像,您需要扩展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;
}
现在,您可以检测用户单击图像并实际找到他们正在单击的图像url,但是我们需要更改-(void)openContextualMenuAtPoint:方法以提供额外的选项
这也是我的(我试着模仿Safari的行为):
(注意:selectedLinkURL和selectedImageURL在.h文件中声明,以便在整个类中访问它们,以便保存或打开后者的链接
到目前为止,我们刚刚回顾了教程中的代码更改,但现在我们将进入教程中没有介绍的内容(在实际提到如何保存图像或打开链接之前,它将停止)
为了处理用户的选择,我们现在需要添加actionSheet:clickedbuttonindex:method
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:@"Open"]){
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:selectedLinkURL]]];
}
else if ([[actionSheet buttonTitleAtIndex:buttonIndex] isEqualToString:@"Copy"]){
[[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];
}
}
这会检查用户想要做什么,并处理/大多数操作,只有“保存图像”操作需要另一种方法来处理。
在.h中的接口声明中添加一个MBProgressHUB*progressHud;,并在init方法中设置它(无论您从哪个类处理webview)
而-(void)saveImageURL:(NSString*)url;方法实际上会将其保存到图像库中。
(更好的方法是通过NSURLRequest进行下载,并在MBProgressHUDModeDeterminate中更新进度hud,以确定下载实际需要的时间,但这是一个更复杂的组合实现)
当然,将[progressHud release];添加到dealloc方法中
希望这能向您展示如何向apple遗漏的webView添加一些选项。
当然,您可以添加更多内容,如instapaper的“以后阅读”选项或“在Safari中打开”按钮。
(看看这篇文章的篇幅,我明白了为什么最初的教程遗漏了最后的实现细节)
编辑:(更新更多信息)
有人问我关于我在顶部掩盖的细节,"tapAndHoldShortNotification"的问题,所以这是在澄清它
这是我的UIWindow子类,它添加了第二个通知以取消默认选择菜单(这是因为当我尝试教程时,它显示了两个菜单)
然后,通知的处理方式如下:
// in -viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopSelection:) name:@"TapAndHoldShortNotification" object:nil];
- (void)stopSelection:(NSNotification*)notification{
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
}
这只是一个小小的改变,但它修复了一个恼人的小错误,你可以看到两个菜单(标准菜单和你的菜单)
此外,您还可以通过在通知发出时发送触摸位置,然后从该位置显示UIActionSheet来轻松添加对iPad的支持,尽管这是在iPad之前编写的,因此不包括对该位置的支持。在这个问题上苦苦挣扎了2或3天之后,位置似乎已经计算出来了“相对”到UIWebView的“左上角”(我正在为iOS 7编程) 因此,为了实现这一点,当您在WebView所在的控制器上获得位置时(我将在下面放一段代码),不要添加“滚动偏移量” 片段-上下文菜单操作:
- (void)contextualMenuAction:(NSNotification*)notification {
// Load javascript
[self loadJavascript];
// Initialize the coordinates
CGPoint pt;
pt.x = [[[notification object] objectForKey:@"x"] floatValue];
pt.y = [[[notification object] objectForKey:@"y"] floatValue];
// Convert point from window to view coordinate system
pt = [self.WebView convertPoint:pt fromView:nil];
// Get PAGE and UIWEBVIEW dimensions
CGSize pageDimensions = [self.WebView documentSize];
CGSize webviewDimensions = self.WebView.frame.size;
/***** If the page is in MOBILE version *****/
if (webviewDimensions.width == pageDimensions.width) {
}
/***** If the page is in DESKTOP version *****/
else {
// convert point from view to HTML coordinate system
CGSize viewSize = [self.WebView frame].size;
// Contiens la portion de la page visible depuis la webview (en fonction du zoom)
CGSize windowSize = [self.WebView windowSize];
CGFloat factor = windowSize.width / viewSize.width;
CGFloat factorHeight = windowSize.height / viewSize.height;
NSLog(@"factor: %f", factor);
pt.x = pt.x * factor; // ** logically, we would add the offset **
pt.y = pt.y * factorHeight; // ** logically, we would add the offset **
}
NSLog(@"x: %f and y: %f", pt.x, pt.y);
NSLog(@"WINDOW: width: %f height: %f", [self.WebView windowSize].width, [self.WebView windowSize].height);
NSLog(@"DOCUMENT: width: %f height: %f", pageDimensions.width, pageDimensions.height);
[self openContextualMenuAt:pt];
}
片段-在OpenContextalMenuat:
- (void)contextualMenuAction:(NSNotification*)notification {
// Load javascript
[self loadJavascript];
// Initialize the coordinates
CGPoint pt;
pt.x = [[[notification object] objectForKey:@"x"] floatValue];
pt.y = [[[notification object] objectForKey:@"y"] floatValue];
// Convert point from window to view coordinate system
pt = [self.WebView convertPoint:pt fromView:nil];
// Get PAGE and UIWEBVIEW dimensions
CGSize pageDimensions = [self.WebView documentSize];
CGSize webviewDimensions = self.WebView.frame.size;
/***** If the page is in MOBILE version *****/
if (webviewDimensions.width == pageDimensions.width) {
}
/***** If the page is in DESKTOP version *****/
else {
// convert point from view to HTML coordinate system
CGSize viewSize = [self.WebView frame].size;
// Contiens la portion de la page visible depuis la webview (en fonction du zoom)
CGSize windowSize = [self.WebView windowSize];
CGFloat factor = windowSize.width / viewSize.width;
CGFloat factorHeight = windowSize.height / viewSize.height;
NSLog(@"factor: %f", factor);
pt.x = pt.x * factor; // ** logically, we would add the offset **
pt.y = pt.y * factorHeight; // ** logically, we would add the offset **
}
NSLog(@"x: %f and y: %f", pt.x, pt.y);
NSLog(@"WINDOW: width: %f height: %f", [self.WebView windowSize].width, [self.WebView windowSize].height);
NSLog(@"DOCUMENT: width: %f height: %f", pageDimensions.width, pageDimensions.height);
[self openContextualMenuAt:pt];
}
要加载正确的JS函数,请执行以下操作:
- (void)openContextualMenuAt:(CGPoint)pt {
// Load javascript
[self loadJavascript];
// get the Tags at the touch location
NSString *tags = [self.WebView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"getHTMLTagsAtPoint(%li,%li);",(long)pt.x,(long)pt.y]];
...
}
代码片段-在JSTools.js中:
- (void)contextualMenuAction:(NSNotification*)notification {
// Load javascript
[self loadJavascript];
// Initialize the coordinates
CGPoint pt;
pt.x = [[[notification object] objectForKey:@"x"] floatValue];
pt.y = [[[notification object] objectForKey:@"y"] floatValue];
// Convert point from window to view coordinate system
pt = [self.WebView convertPoint:pt fromView:nil];
// Get PAGE and UIWEBVIEW dimensions
CGSize pageDimensions = [self.WebView documentSize];
CGSize webviewDimensions = self.WebView.frame.size;
/***** If the page is in MOBILE version *****/
if (webviewDimensions.width == pageDimensions.width) {
}
/***** If the page is in DESKTOP version *****/
else {
// convert point from view to HTML coordinate system
CGSize viewSize = [self.WebView frame].size;
// Contiens la portion de la page visible depuis la webview (en fonction du zoom)
CGSize windowSize = [self.WebView windowSize];
CGFloat factor = windowSize.width / viewSize.width;
CGFloat factorHeight = windowSize.height / viewSize.height;
NSLog(@"factor: %f", factor);
pt.x = pt.x * factor; // ** logically, we would add the offset **
pt.y = pt.y * factorHeight; // ** logically, we would add the offset **
}
NSLog(@"x: %f and y: %f", pt.x, pt.y);
NSLog(@"WINDOW: width: %f height: %f", [self.WebView windowSize].width, [self.WebView windowSize].height);
NSLog(@"DOCUMENT: width: %f height: %f", pageDimensions.width, pageDimensions.height);
[self openContextualMenuAt:pt];
}
这是我用来触摸元素的函数
function getHTMLTagsAtPoint(x,y) {
var tags = ",";
var element = document.elementFromPoint(x,y);
while (element) {
if (element.tagName) {
tags += element.tagName + ',';
}
element = element.parentNode;
}
return tags;
}
代码片段-加载JavaScript
我用这个在webview中注入我的JS代码
-(void)loadJavascript {
[self.WebView stringByEvaluatingJavaScriptFromString:
[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JSTools" ofType:@"js"] encoding:NSUTF8StringEncoding error:nil]];
}
这一部分(我所做的一切都超越了默认的UIActionSheet)是基于
@Freerunning的答案是完整的(我几乎完成了他在我的其他课程中所说的一切,就像我的代码所基于的帖子上所说的),我发布的代码片段只是为了向您更“完整”地展示我的代码
希望这有帮助!首先感谢Freerunnering提供的伟大解决方案 但您可以使用UILongPressGestureRecognitor而不是自定义的LongPress识别器来实现这一点。这使得实现起来更加容易: 在包含webView的Viewcontroller中: 将UIgestureRecognitizerDelegate添加到ViewController
let mainJavascript = "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; }"
func viewDidLoad() {
...
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(CustomViewController.longPressRecognizerAction(_:)))
self.webView.scrollView.addGestureRecognizer(longPressRecognizer)
longPressRecognizer.delegate = self
...
}
func longPressRecognizerAction(sender: UILongPressGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Began {
let tapPostion = sender.locationInView(self.webView)
let tags = self.webView.stringByEvaluatingJavaScriptFromString("MyAppGetHTMLElementsAtPoint(\(tapPostion.x),\(tapPostion.y));")
let href = self.webView.stringByEvaluatingJavaScriptFromString("MyAppGetLinkHREFAtPoint(\(tapPostion.x),\(tapPostion.y));")
let src = self.webView.stringByEvaluatingJavaScriptFromString("MyAppGetLinkSRCAtPoint(\(tapPostion.x),\(tapPostion.y));")
print("tags: \(tags)\nhref: \(href)\nsrc: \(src)")
// handle the results, for example with an UIDocumentInteractionController
}
}
// Without this function, the customLongPressRecognizer would be replaced by the original UIWebView LongPressRecognizer
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
就这样!tapAndHoldShortNotification在哪里使用?Ridcardo:我在底部更新了帖子,并提供了更多信息。如果我没有向下滚动,效果会很好。但是,在向下滚动网络视图,然后长按时,这不起作用。可能它没有计算正确的触摸点
-(void)loadJavascript {
[self.WebView stringByEvaluatingJavaScriptFromString:
[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"JSTools" ofType:@"js"] encoding:NSUTF8StringEncoding error:nil]];
}
let mainJavascript = "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; }"
func viewDidLoad() {
...
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(CustomViewController.longPressRecognizerAction(_:)))
self.webView.scrollView.addGestureRecognizer(longPressRecognizer)
longPressRecognizer.delegate = self
...
}
func longPressRecognizerAction(sender: UILongPressGestureRecognizer) {
if sender.state == UIGestureRecognizerState.Began {
let tapPostion = sender.locationInView(self.webView)
let tags = self.webView.stringByEvaluatingJavaScriptFromString("MyAppGetHTMLElementsAtPoint(\(tapPostion.x),\(tapPostion.y));")
let href = self.webView.stringByEvaluatingJavaScriptFromString("MyAppGetLinkHREFAtPoint(\(tapPostion.x),\(tapPostion.y));")
let src = self.webView.stringByEvaluatingJavaScriptFromString("MyAppGetLinkSRCAtPoint(\(tapPostion.x),\(tapPostion.y));")
print("tags: \(tags)\nhref: \(href)\nsrc: \(src)")
// handle the results, for example with an UIDocumentInteractionController
}
}
// Without this function, the customLongPressRecognizer would be replaced by the original UIWebView LongPressRecognizer
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}