2010-06-25 54 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]);