iPad UIWebView在href链接坐标上定位UIPopoverController视图

时间:2010-06-25 13:34:25

标签: cocoa-touch ipad uiwebview uipopovercontroller

我希望这个问题不是一个愚蠢的问题,但是如何在UIWebView上定位UIPopoverController视图,以便弹出视图箭头指向被点击以显示它的UIWebView链接?

我正在使用委托方法;

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

}

捕获并路由点击但我不确定如何获取链接坐标以定位弹出视图。

非常感谢任何帮助或指向相关信息的指针。

3 个答案:

答案 0 :(得分:7)

我有一个有效的解决方案,但我认为有更好的方法。

我创建了一个继承自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的文档说你不应该继承它。我想有一个更好的方法,但这确实有效。你找到了另一种解决方案吗?

答案 1 :(得分: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中,否则确定偏移变得更复杂。

答案 2 :(得分: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]);