4

この質問がばかげた質問ではないことを願っていますが、ポップアップビューの矢印がクリックされて表示されたUIWebViewリンクを指すように、UIWebView上にUIPopoverControllerビューを配置するにはどうすればよいですか?

私はデリゲートメソッドを使用しています。

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

}

クリックをキャプチャしてルーティングしますが、ポップアップビューを配置するためのリンク座標を取得する方法がわかりません。

ヘルプや関連情報へのポインタをいただければ幸いです。

4

3 に答える 3

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は、サブクラス化すべきではないと書かれているため、良くありません。もっと良い方法があると思いますが、これはうまくいきます。別の解決策を見つけましたか?

于 2010-07-30T21:34:42.873 に答える
2

各リンクに一意の ID を付与し、その ID を "myscheme:" ロジックを介して 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 に埋め込まれていないか、オフセットの決定がより複雑になるのではなく、階層の最上位にあることを願っています。

于 2011-06-17T21:20:07.727 に答える
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]);                                      
于 2015-11-18T08:21:32.123 に答える