8 ответов:
добавьте это в делегат UIWebView:
(отредактировано для проверки типа навигации. вы также можете пройти через
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 будет выглядеть так в Свифт:
func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool { if navigationType == UIWebViewNavigationType.LinkClicked { UIApplication.sharedApplication().openURL(request.URL) return false } return true }
один быстрый комментарий к ответу пользователя 306253: внимание с этим, когда вы пытаетесь загрузить что-то в UIWebView самостоятельно (т. е. даже из кода), этот метод предотвратит это произошло.
что вы можете сделать, чтобы предотвратить это (спасибо Уэйд) - это:
if (inType == UIWebViewNavigationTypeLinkClicked) { [[UIApplication sharedApplication] openURL:[inRequest URL]]; return NO; } return YES;вы также можете обрабатывать
UIWebViewNavigationTypeFormSubmittedиUIWebViewNavigationTypeFormResubmittedтипы.
у других ответов есть одна проблема: они полагаются на действие, которое вы делаете, а не на саму ссылку, чтобы решить, загружать ли ее в Safari или в webview.
иногда это именно то, что вы хотите, и это нормально; но в некоторых других случаях, особенно если у вас есть якорные ссылки на Вашей странице, вы действительно хотите открыть только внешние ссылки в Safari, а не внутренние. В этом случае вы должны проверить
URL.hostсвойства вашего запроса.Я использую этот кусок кода чтобы проверить, есть ли у меня имя хоста в URL, который анализируется, или если он встроен 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; } }вы можете, конечно, адаптировать регулярное выражение в соответствии с вашими потребностями.
в 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 и navigationType.
вот Xamarin iOS эквивалент ответа drawnonward.
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; } }
принятый ответ не работает.
если ваша страница загружает URL-адреса через Javascript, то
navigationTypeбудетUIWebViewNavigationTypeOther. Что, к сожалению, также включает фоновые загрузки страниц, такие как аналитика.чтобы обнаружить навигацию по страницам, вам нужно сравнить
[request URL]до[request mainDocumentURL].это решение будет работать во всех случаях:
- (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; } }
в моем случае я хочу убедиться, что абсолютно все в веб-представлении открывается Safari, кроме начальной загрузки, и поэтому я использую...
- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType { if(inType != UIWebViewNavigationTypeOther) { [[UIApplication sharedApplication] openURL:[inRequest URL]]; return NO; } return YES; }
Comments