我正在 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 秒内点击了两个不同的位置,例如第一次点击是在超链接上,第二次点击是在“UIWebview
中的其他地方” , UIPopover
仅出现在第二个点击位置,而不是超链接位置。
我必须仅根据超链接位置显示 UIPopover
,而不是在其他位置。如何解决此问题?
最佳答案
使用叠加 View
用点击通过的覆盖替换您注册点击位置的方法。
UITapGestureRecognizer
有以下限制:- 当点击发生在超链接之外时,它会记录其位置,这要归功于
UITapGestureRecognizer
。 - 不幸的是,
UIWebview
超链接点击优先于手势识别器,您永远无法获得质心
。这才是真正的问题,导致弹出框显示错位。
- 当点击发生在超链接之外时,它会记录其位置,这要归功于
UIPopoverController
在 iOS 9 中被弃用。"UIPopoverController is deprecated. Popovers are now implemented as UIViewController presentations. Use a modal presentation style of UIModalPresentationPopover and UIPopoverPresentationController."
tapAction
和shouldStartLoadWithRequest
不耦合,可以彼此独立发生。此外,它们基本上是相互排斥的。
使用叠加层在该 View 中注册位置,然后点击下方的 View 。 如果您的叠加层和 WebView 具有相同的框架,您可以互换使用点击位置。覆盖将保证紧密耦合,您的方法的其余部分将按设计工作。
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
}
}
委托(delegate)
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 的更多详细信息.
关于objective-c - UIWebview中如何获取超链接的坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32670551/