加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

objective-c – 如何在UIWebview中获取Hyperlink的坐标

发布时间:2020-12-14 17:34:27 所属栏目:百科 来源:网络整理
导读:我正在UIWebview中加载pdf(具有多个超链接)文档.我必须动态地在超链接上显示UIPopover. 我可以使用TapGesture Action方法捕获超链接的坐标 - (void)tapAction:(UITapGestureRecognizer *)sender { self.point = [sender locationInView:self.myWebView]; }
我正在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中的其他地方”,UIPopover仅在第二个点击位置呈现,而不是在超链接位置.
我必须仅基于超链接位置显示UIPopover,而不是在其他位置.我如何解决此问题?

解决方法

使用叠加视图

>替换您的方法以通过点按覆盖来注册点击位置. UITapGestureRecognizer具有以下限制:

>当超级链接发生在超链接之外时,由于UITapGestureRecognizer,它会注册其位置.
>不幸的是,UIWebview超链接点击优先于手势识别器,你永远不会得到质心.这是真正的问题,导致弹出窗口错位.

> iOS 9中不推荐使用UIPopoverController.

“UIPopoverController is deprecated. Popovers are now implemented as UIViewController presentations. Use a modal presentation style of UIModalPresentationPopover and UIPopoverPresentationController.”

> tapAction和shouldStartLoadWithRequest没有耦合,并且可以彼此独立地发生.而且,它们基本上是相互排斥的.

enter image description here

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

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找到其他详细信息.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读