2010-06-25 60 views
4

我希望这个问题不是一个愚蠢的,但如何定位UIPopoverController视图通过UIWebView,使弹出视图箭头指向UIWebView点击链接显示它?iPad的UIWebView定位UIPopoverController视图在href链接coords

我正在使用委托方法;

-(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType { 
if ([[[inRequest URL] absoluteString] hasPrefix:@"myscheme:"]) { 
//UIPopoverController stuff here 
return NO; 
} 

}

捕捉和路由的点击,但我不能确定如何获得链接COORDS定位弹出视图。

任何帮助或指向相关信息将非常感激。

回答

7

我有一个解决方案,但我认为有一个更好的方法来做到这一点。

我创建了一个TouchableWebView,它继承自UIWebView并保存方法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; 
} 

这不好,因为的文档说,你不应该继承它。我想有更好的方法,但这确实有效。你找到另一种解决方案吗?

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中,否则确定偏移量会变得更加复杂。

1

对我而言,使用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]);