UIWebView在Safari中打开链接

我有一个非常简单的UIWebView与我的应用程序包中的内容。 我希望在Web视图中的任何链接在Safari中打开,而不是在Web视图中打开。 这可能吗?

将此添加到UIWebView委托:

(编辑检查导航types,你也可以通过file://请求这将是相对链接)

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if (navigationType == UIWebViewNavigationTypeLinkClicked ) { [[UIApplication sharedApplication] openURL:[request URL]]; return NO; } return YES; } 

Swift版本:

 func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool { if navigationType == UIWebViewNavigationType.LinkClicked { UIApplication.sharedApplication().openURL(request.URL!) return false } return true } 

Swift 3版本:

 func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool { if navigationType == UIWebViewNavigationType.linkClicked { UIApplication.shared.openURL(request.url!) return false } return true } 

更新

由于openURL在iOS 10中已被弃用:

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if (navigationType == UIWebViewNavigationTypeLinkClicked ) { UIApplication *application = [UIApplication sharedApplication]; [application openURL:[request URL] options:@{} completionHandler:nil]; return NO; } return YES; } 

如果有人想知道,Drawnonward的解决scheme将在Swift中看起来像这样:

 func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool { if navigationType == UIWebViewNavigationType.LinkClicked { UIApplication.sharedApplication().openURL(request.URL) return false } return true } 

对user306253的回答一个简短的评论:谨慎与此,当你尝试自己(即使从代码)加载的东西在UIWebView,这种方法将阻止它发生。

你可以做什么来防止这个(感谢韦德)是:

 if (inType == UIWebViewNavigationTypeLinkClicked) { [[UIApplication sharedApplication] openURL:[inRequest URL]]; return NO; } return YES; 

您可能还想要处理UIWebViewNavigationTypeFormSubmittedUIWebViewNavigationTypeFormResubmittedtypes。

其他的答案有一个问题:他们依靠你所做的动作,而不是链接本身来决定是否加载在Safari或web视图。

现在有时候这正是你想要的,这很好; 但有些时候,特别是如果你的页面上有锚链接的话,你只需要在Safari中打开外部链接,而不是内部链接。 在这种情况下,您应该检查请求的URL.host属性。

我使用这段代码来检查是否在被parsing的URL中有一个主机名,或者是否embedded了html:

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { static NSString *regexp = @"^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9-]*[a-zA-Z0-9])[.])+([A-Za-z]|[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9])$"; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regexp]; if ([predicate evaluateWithObject:request.URL.host]) { [[UIApplication sharedApplication] openURL:request.URL]; return NO; } else { return YES; } } 

你当然可以适应正则expression式来适应你的需求。

在Swift中你可以使用下面的代码:

 extension YourViewController : UIWebViewDelegate { func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool { if let url = request.URL where navigationType == UIWebViewNavigationType.LinkClicked { UIApplication.sharedApplication().openURL(url) return false } return true } } 

确保检查URL值和导航types。

下面是Xamarin iOS对应的拉丁答案。

 class WebviewDelegate : UIWebViewDelegate { public override bool ShouldStartLoad (UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType) { if (navigationType == UIWebViewNavigationType.LinkClicked) { UIApplication.SharedApplication.OpenUrl (request.Url); return false; } return true; } } 

在我的情况下,我想确保绝对一切在Web视图中打开Safari,除了初始加载,所以我使用…

 - (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType { if(inType != UIWebViewNavigationTypeOther) { [[UIApplication sharedApplication] openURL:[inRequest URL]]; return NO; } return YES; } 

接受的答案不起作用。

如果您的页面通过Javascript加载url,则navigationType将为UIWebViewNavigationTypeOther 。 不幸的是,其中还包括后台页面加载,如分析。

要检测页面导航,您需要将[request URL][request mainDocumentURL]

这个解决scheme将在所有情况下工作:

 - (BOOL)webView:(UIWebView *)view shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)type { if ([[request URL] isEqual:[request mainDocumentURL]]) { [[UIApplication sharedApplication] openURL:[request URL]]; return NO; } else { return YES; } }