如何在UIWebView中添加弹出按钮

时间:2012-10-18 12:55:24

标签: iphone ios uiwebview popup

当我长按UIWebView的任何网址中的音乐播放选项时,会打开聋人弹出窗口。 我想在弹出窗口中添加一个按钮..是否可以这样做..

就像我想添加FETCH按钮一样。

我可以更改默认弹出功能OPENCOPY。如下所示

enter image description here

我通过谷歌来了解 -

首先,您实际上无法将其他菜单项添加到标准上下文菜单的默认菜单项中。但您可以使用某个CSS属性关闭上下文菜单。所以解决方案是关闭默认菜单并从头开始实现自己的菜单。要实现自己的上下文菜单,您必须首先捕获标签并保持手势,在屏幕上获取手指的坐标,将这些坐标转换为网页的坐标系,最后在以下位置查找HTML元素这个位置。

3 个答案:

答案 0 :(得分:5)

新答案:

看起来这就是我们想要的,这里:

https://stackoverflow.com/a/3198220/700471

老答案:

好的,经过一些研究,这是交易:

您在问题中描述的内容似乎准确无误:

  

首先,你真的无法添加额外的菜单项   默认的标准上下文菜单。但你可以关掉   使用某个CSS属性的上下文菜单。所以解决方案   将关闭默认菜单并实现自己的   刮。要实现自己的上下文菜单,您必须先行   捕捉标签并按住手势,获取手指的坐标   屏幕,将这些坐标转换为坐标系   网页,最后在这个位置查找HTML元素。

所以你打算用上下文菜单实现你自己的popover控制器 - 很好,我根本不会涉及到这一点,我会假设你知道如何做到这一点。

您的问题似乎是,如何在UIWebView中进行长按手势并将其转换为网页的坐标以查找所选的DOM元素,并将其用作上下文生成你的弹出菜单。

我发现的是this,特别是this这行代码:

NSString *js = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).innerHTML", touchPoint.x, touchPoint.y];

看起来像JS你需要弄清楚什么元素刚刚被按下了,当然你需要做一些人物形象来看看它是否是一个链接和从那里执行你的上下文菜单,但这不是我已经研究过的东西。

进一步的想法:

最简单的方法可能是将UILongPressGestureRecognizer附加到您的UIWebView(这可以在笔尖中轻松完成),并确保“已发送操作”指向ViewController上的相应IBAction。 (我想你也可以使用委托出口,但我从来不需要这样做。)

在任何情况下,您都可以使用手势识别器的locationOfTouch:inView:方法,您可能想要使用的视图将是UIWebView的内容视图,我相信您可以使用{{1 (如果您没有使用新的数组索引下标,则为objectAtIndex:变体)。

无论如何,我认为我提供了足够的答案来回答你的问题。


编辑:

好的,所以你仍然遇到这个问题,所以我去做了一个测试项目并让它运行起来。有一点令人讨厌的是,WebKit以某种方式在DOM中的对象周围添加了一个“缓冲区”区域,这意味着如果你轻轻触摸旁边的一个链接,它仍会突出显示,但是当你使用它时JS命令myWebView.scrollView.subviews[0]它没有这样做,所以你必须更仔细地触摸以使用此方法触发弹出窗口。但是,它有效。

我使用“单一视图”模板制作了一个空白项目,并向xib中添加了elementFromPoint,将其UIWebView出口指向文件所有者。然后我将delegate放入xib,附加到UIWebView。我将其UILongPressGestureRecognizer设置为文件所有者,并将其delegate出口设置为文件所有者中的selector IBAction。我还在Interface Builder的识别器属性中取消选中“在视图中取消”。

以下是视图控制器的代码。

接口:

longPressDetected

实现:

//
//  WVTViewController.h
//  WebViewTest
//

#import <UIKit/UIKit.h>

@interface WVTViewController : UIViewController <UIWebViewDelegate, UIGestureRecognizerDelegate>

@property (nonatomic, weak) IBOutlet    UIWebView   *myWebView;
@property (nonatomic)                   BOOL        didFirstLoad;

- (IBAction)longPressDetected:(id)sender;

@end

正如我所说,我测试了上面的代码,它运行正常。您当然可以更改JS并使用// // WVTViewController.m // WebViewTest // #import "WVTViewController.h" @interface WVTViewController () @end @implementation WVTViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // Just load google. NSURL *theURL = [NSURL URLWithString:@"http://www.google.com"]; NSURLRequest *request = [NSURLRequest requestWithURL:theURL]; [self.myWebView loadRequest:request]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)webViewDidFinishLoad:(UIWebView *)webView { if (!self.didFirstLoad) { // Disable the default contextual menu. [webView stringByEvaluatingJavaScriptFromString:@"document.body.style.webkitTouchCallout='none';"]; } } // Called by the gesture recognizer. - (IBAction)longPressDetected:(UILongPressGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateBegan) { NSLog(@"Long press detected."); CGPoint webViewCoordinates = [sender locationInView:self.myWebView]; NSLog(@"WebView coordinates are: %@", NSStringFromCGPoint(webViewCoordinates)); // Find the DOM element NSString *locatorString = [NSString stringWithFormat:@"document.elementFromPoint(%f, %f).innerHTML", webViewCoordinates.x, webViewCoordinates.y]; NSString *result = [self.myWebView stringByEvaluatingJavaScriptFromString: locatorString]; NSLog(@"Element Found: %@", result); } } // Necessary or the gesture recognizer won't call the IBAction. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; } @end 之外的其他内容,例如innerHTMLtagName或您喜欢的任何内容。您可能需要进行多次检查,可能需要使用排队的JS命令(这将是蹩脚的),除非您可以JSON字符串化DOM对象,将其传递回Objective-C,转换为本机对象和在那个环境中执行你的检查 - 但是,我不是JS专业人员,我不打算对此进行调查。

作为一个注释,我有点惊讶于href的坐标是UIWebView本身的触摸坐标。我编写了一整段代码,遍历elementFromPoint并找到内容视图,然后在该视图上调用myWebView.scrollView.subviews。但是我得到了时髦的行为,所以在预感中我使用了webview坐标并且它工作得很好,即使在一个大的网页上我滚动到一边向下。我怀疑webview中的某种Apple编程行为可能会转换这些坐标。可能是JS的坐标系根据内容视图在scrollview中移动的方式而改变 - 这对我来说是最有意义的。

答案 1 :(得分:2)

回答此问题的正确而准确的方法是链接

http://www.icab.de/blog/2010/07/11/customize-the-contextual-menu-of-uiwebview/

答案 2 :(得分:0)

您可以使用以下内容触发事件:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
  if( navigationType == UIWebViewNavigationTypeLinkClicked )
  {
    // Handle your URL click here (open the popup menu)
    // ...
    return NO;
  }
  return YES;
}

不要忘记委派UIWebView