如何在UIWebview中获取Hyperlink的坐标

时间:2015-09-19 16:25:54

标签: objective-c xcode uiwebview uipopovercontroller uitapgesturerecognizer

我正在UIWebview加载pdf(有多个超链接)文档。我必须动态地在超链接上显示UIPopover

我可以使用TapGesture Action方法

捕获超链接的坐标
- (void)tapAction:(UITapGestureRecognizer *)sender    
{
    self.point = [sender locationInView:self.myWebView];  
}

使用以下方法

显示UIPopover超链接
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL *rqstUrl = [request URL];
    if (([[rqstUrl scheme] isEqualToString: @"https"] || [[rqstUrl scheme] isEqualToString: @"http"]) && (navigationType == UIWebViewNavigationTypeLinkClicked))
    {
        [self.myWebView stopLoading];
        CGRect rect = CGRectMake(self.point.x,self.point.y-5, 5, 5);
        UIPopoverController *popController = [[UIPopoverController alloc] initWithContentViewController:contentViewController];
        popController.popoverContentSize = CGSizeMake(500, 200);
        self.popController = popController;
        self.popController.delegate =self;
        UIPopoverArrowDirection direction = UIPopoverArrowDirectionUp|UIPopoverArrowDirectionDown;
        self.popController.popoverLayoutMargins = UIEdgeInsetsMake(0, rect.origin.x, 1, 1);
        [self.popController presentPopoverFromRect:rect inView:webView permittedArrowDirections:direction animated:YES];
    }
    return YES;
}

但问题是,如果我在1秒或2秒内点击了两个不同的位置,例如First Tap On Hyperlink ,而Second Tap就在" UIWebview& #34;,UIPopover仅在第二个分接位置呈现,而不是在超链接位置。 我必须仅基于超链接位置显示UIPopover,而不是在其他位置显示。我如何解决此问题?

1 个答案:

答案 0 :(得分:3)

使用叠加视图

  1. 将您的方法替换为通过点按叠加注册点击位置。 UITapGestureRecognizer有以下限制:

    • 当超级链接发生在超链接之外时,由于UITapGestureRecognizer,它确实会注册其位置。
    • 不幸的是,UIWebview超链接点击优先于手势识别器,您永远不会得到centroid。这是真正的问题,导致弹出窗口错位。
  2. 在iOS 9中不推荐使用
  3. UIPopoverController

      

    “不推荐使用UIPopoverController。现在将Popovers实现为UIViewController演示文稿。使用UIModalPresentationPopover和UIPopoverPresentationController的模式演示样式。”

  4. tapActionshouldStartLoadWithRequest未耦合,可以彼此独立发生。此外,它们基本上是相互排斥的。

  5. enter image description here

    使用叠加层在该视图中注册位置,然后点击下方的视图。 如果您的叠加层和网络视图具有相同的框架,您可以互换使用分接位置。叠加层将保证紧密耦合,其余方法将按设计工作。

    class TapOverlayView: UIView {
        var centroid:CGRect = CGRect.zero
    
        override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
            centroid = CGRect(origin: point, size: CGSize(width: 1, height: 1))
            return nil // tap through
        }
    }
    

    <强>代表

    extension ViewController: UIWebViewDelegate {
        public func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
            let rqstUrl = request.url
    
            if( rqstUrl!.scheme?.contains("http"))! && ( .linkClicked == navigationType) {
                webView.stopLoading()
    
                let contentViewController = storyboard!.instantiateViewController(withIdentifier: "popover")
                contentViewController.modalPresentationStyle = .popover
                contentViewController.preferredContentSize = CGSize(width: 200, height: 40)
    
                if let popController = contentViewController.popoverPresentationController {
                    popController.permittedArrowDirections = .down
                    popController.sourceView = webView
                    popController.sourceRect = CGRect(origin: tap.centroid.origin, size: CGSize.zero)
                    present(contentViewController, animated: true, completion: nil)
                }
            }
            return true
        }
    }
    

    ►在GitHub上找到此解决方案,并在Swift Recipes上找到其他详细信息。