41

我在我的 iPhone 应用程序中嵌入了一个 UIWebView。我希望能够将该 web 视图中的某些链接打开到完整的 Mobile Safari 应用程序中(即不是我的嵌入式版本)。

有没有一种简单的方法来构建我的一些hrefs来强制这样做,而不是在我的嵌入式webview中打开每个链接?

谢谢。

4

5 回答 5

60

为了扩展 Randy 所说的,这是我在我的应用程序中使用的,用于在外部 Safari 或 Mail 应用程序中打开每个 http://、https:// 和 mailto:// URL:

-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType; 
{
    NSURL *requestURL =[ [ request URL ] retain ]; 
    if ( ( [ [ requestURL scheme ] isEqualToString: @"http" ] || [ [ requestURL scheme ] isEqualToString: @"https" ] || [ [ requestURL scheme ] isEqualToString: @"mailto" ]) 
        && ( navigationType == UIWebViewNavigationTypeLinkClicked ) ) { 
        return ![ [ UIApplication sharedApplication ] openURL: [ requestURL autorelease ] ]; 
    } 
    [ requestURL release ]; 
    return YES; 
}

正如 Randy 所说,您将希望在您设置为 UIWebView 委托的任何类中实现这一点。要仅选择 URL 启动 Safari,您可以将其方案从 http:// 更改为 safari:// 或类似的东西,并且仅将这些 URL 踢到系统(在将自定义 URL 方案替换为 http:// 之后) .

我在我的内部帮助文档中执行此操作,该文档是在 UIWebView 中显示的 HTML,因此在我的应用程序中嵌入了通用 Web 浏览器时,我不会在审核过程中遇到问题。

于 2010-03-28T12:32:28.057 回答
20

好,我知道了。也许它不是完美的解决方案,但你可以这样做:

仅在您的WebViewController.m

将该行添加webView.delegate = self;viewDidLoad过程中:

- (void)viewDidLoad {
    webView.delegate = self;
    .... your code ....
}

然后,您可以按照上述 Controller.m布尔结果函数在 File 中的某处添加:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if (navigationType == UIWebViewNavigationTypeLinkClicked) {
        [[UIApplication sharedApplication] openURL:request.URL];
        return false;
    }
    return true;
}
于 2010-12-31T21:08:39.237 回答
12

我自己没有尝试过,但我认为你可以实现 UIWebViewDelegate 方法

webView:shouldStartLoadWithRequest:navigationType 

任何时候点击 UIWebView 中的链接都会调用它。在该方法中,您只需要确定单击的链接是否应该导致启动 Safari 并在应该时使用 openURL。

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {

    // Check if this was a click event and then some other criteria for determining if you want to launch Safari.
    if (navigationType == UIWebViewNavigationTypeLinkClicked && [Some other criteria]) {
        [[UIApplication sharedApplication] openURL:request.URL];

        // Return false to indicate to the UIWebView to not navigate to the linked target
        return false;
    }

    // Return true so that the UIWebView loads the link target
    return true;
}

不要忘记您需要将 UIWebView 委托属性设置为实现 UIWebViewDelegate 的类的实例。

于 2010-03-28T10:32:55.187 回答
1

这就是我们解决它的方法,将其添加到您的 ViewController.m 文件中:

    - (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    first.delegate = (id)self;
                [first loadRequest:[NSURLRequest requestWithURL:[NSURL     URLWithString:@"http://my.FellowshipNWA.org?publicapp"]]];
}

// Add section below so that external links & PDFs will open in Safari.app
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request     navigationType:(UIWebViewNavigationType)navigationType {
    if (navigationType == UIWebViewNavigationTypeOther) {
        NSString *checkURL = @"http://my.fellowshipnwa.org/?givenowsafari";
        NSString *reqURL = request.URL.absoluteString;
        if ([reqURL isEqualToString:checkURL])
             {
                 [[UIApplication sharedApplication] openURL:request.URL];
            return false;
    }
        else {
            return true;
        }
    }
    return true;
}
于 2013-07-25T20:28:14.920 回答
1

斯威夫特版本的布拉德拉森的回答:

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {

    var url: NSURL = request.URL!
    var isExternalLink: Bool = url.scheme == "http" || url.scheme == "https" || url.scheme == "mailto"
    if (isExternalLink && navigationType == UIWebViewNavigationType.LinkClicked) {
        return !UIApplication.sharedApplication().openURL(request.URL!)
    } else {
        return true
    }
}
于 2015-06-04T16:01:59.610 回答