iPad UIWebView 在 href 链接坐标处定位 UIPopoverController 视图
Posted
技术标签:
【中文标题】iPad UIWebView 在 href 链接坐标处定位 UIPopoverController 视图【英文标题】:iPad UIWebView position a UIPopoverController view at a href link coords 【发布时间】:2010-06-25 13:34:24 【问题描述】:我希望这个问题不是一个愚蠢的问题,但是如何将 UIPopoverController 视图定位在 UIWebView 上,以便弹出视图箭头指向被单击以显示它的 UIWebView 链接?
我正在使用委托方法;
-(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType
if ( [[[inRequest URL] absoluteString] hasPrefix:@"myscheme:"] )
//UIPopoverController stuff here
return NO;
捕获和路由点击,但我不确定如何获取链接坐标以定位弹出视图。
非常感谢任何帮助或指向相关信息的指针。
【问题讨论】:
【参考方案1】:我有一个可行的解决方案,但我认为有更好的方法。
我创建了一个继承自 UIWebView 的 TouchableWebView,并将触摸位置保存在方法 hitTest 中。之后,您需要为您的 webview 设置一个委托并实现方法-webView:shouldStartLoadWithRequest:navigationType:
TouchableWebView.h:
@interface TouchableWebView : UIWebView
CGPoint lastTouchPosition;
@property (nonatomic, assign) CGPoint lastTouchPosition;
TouchableWebView.m:
// I need to retrieve the touch position in order to position the popover
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
self.lastTouchPosition = point;
return [super hitTest:point withEvent:event];
在 RootViewController.m 中:
[self.touchableWebView setDelegate:self];
// WebView delegate, when hyperlink clicked
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
if (navigationType == UIWebViewNavigationTypeLinkClicked)
CGPoint touchPosition = [self.view convertPoint:self.touchableWebView.lastTouchPosition fromView:self.touchableWebView];
[self displayPopOver:request atPosition:touchPosition isOnCelebrityFrame:FALSE];
return FALSE;
return TRUE;
这不好,因为UIWebView
的文档说你不应该继承它。我想有一个更好的方法,但这确实有效。您找到其他解决方案了吗?
【讨论】:
【参考方案2】:给每个链接一个唯一的 ID 并通过您的“myscheme:”逻辑将该 ID 传递给您的 Obj-C 代码。
然后您可以通过 javascript 调用确定链接在 UIWebView 中的左侧和顶部偏移量:
NSString *leftJS = [NSString stringWithFormat:@"document.getElementById('%d').offsetLeft - scrollX", linkID];
NSInteger leftOffset = [[currentTextView stringByEvaluatingJavaScriptFromString:js] intValue];
NSString *topJS = [NSString stringWithFormat:@"document.getElementById('%d').offsetTop - scrollY", linkID];
NSInteger topOffset = [[currentTextView stringByEvaluatingJavaScriptFromString:js] intValue];
减去 scrollX/scrollY 说明用户向左或向下滚动了多少 UIWebView。
我的理解是 offsetLeft 和 offsetTop 返回元素在其父元素中的偏移量。因此,希望您的链接位于层次结构的顶部,而不是嵌入到 div 中,否则确定偏移量会变得更加复杂。
【讨论】:
【参考方案3】:对我来说,使用 getBoundingClientRect()
并将其转换为 CGRect
效果很好。
NSString *js = [NSString stringWithFormat:@"JSON.stringify($(\"a[href='%@']\")[0].getBoundingClientRect())", [inRequest URL]];
// top:, right:, bottom:, left:, width:, height:
NSString *rectJson = [webView stringByEvaluatingJavaScriptFromString:js];
NSError *error = nil;
NSDictionary *rectDict = [NSJSONSerialization JSONObjectWithData:[rectJson dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:&error];
if (error)
NSLog(@"json deserialization failed: %@\n%@", rectJson, error);
CGRect rect = CGRectMake([rectDict[@"left"] floatValue], [rectDict[@"top"] floatValue], [rectDict[@"width"] floatValue], [rectDict[@"height"] floatValue]);
【讨论】:
以上是关于iPad UIWebView 在 href 链接坐标处定位 UIPopoverController 视图的主要内容,如果未能解决你的问题,请参考以下文章
摆脱 iOs UIWebView 中的链接单击“flash”指示器