J'ai un très simple UIWebView avec le contenu de mon paquet d'application. J'aimerais que tous les liens de la vue Web s'ouvrent dans Safari plutôt que dans la vue Web. Est-ce possible?
Ajoutez ceci au délégué UIWebView:
(édité pour vérifier le type de navigation. vous pouvez également passer par les requêtes file://
qui seraient des liens relatifs)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
Version rapide:
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 version:
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.linkClicked {
UIApplication.shared.openURL(request.url!)
return false
}
return true
}
Version Swift 4:
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
guard let url = request.url, navigationType == .linkClicked else { return true }
UIApplication.shared.open(url, options: [:], completionHandler: nil)
return false
}
Mise à jour
Comme openURL
est obsolète dans 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;
}
Si quelqu'un se le demande, la solution de Drawnonward ressemblera à ceci dans Swift :
func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
UIApplication.sharedApplication().openURL(request.URL)
return false
}
return true
}
Un commentaire rapide sur la réponse de user306253: attention, lorsque vous essayez de charger quelque chose dans UIWebView (c'est-à-dire même à partir du code), cette méthode l'empêche de se produire.
Ce que vous pouvez faire pour empêcher cela (merci Wade), c'est:
if (inType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
Vous pouvez également vouloir gérer les types UIWebViewNavigationTypeFormSubmitted
et UIWebViewNavigationTypeFormResubmitted
.
Les autres réponses ont un problème: elles dépendent de l'action que vous faites et non du lien lui-même pour décider de le charger dans Safari ou dans la visualisation Web.
Maintenant, parfois c'est exactement ce que vous voulez, ce qui est bien; mais d'autres fois, surtout si vous avez des liens d'ancrage dans votre page, vous voulez vraiment ouvrir uniquement les liens externes dans Safari, et non les liens internes. Dans ce cas, vous devriez vérifier la propriété URL.Host
de votre demande.
J'utilise cette partie de code pour vérifier si l'URL analysée contient un nom d'hôte ou s'il contient du code HTML incorporé:
- (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;
}
}
Vous pouvez bien sûr adapter l’expression régulière à vos besoins.
Dans Swift, vous pouvez utiliser le code suivant:
extension YourViewController: UIWebViewDelegate {
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
if let url = request.url, navigationType == UIWebView.NavigationType.linkClicked {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
return false
}
return true
}
}
Assurez-vous de vérifier la valeur de l'URL et le type de navigation.
Voici l'équivalent Xamarin iOS de la réponse de drawonward.
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;
}
}
La réponse acceptée ne fonctionne pas.
Si votre page charge des URL via Javascript, la navigationType
sera UIWebViewNavigationTypeOther
. Ce qui, malheureusement, inclut également des chargements de page en arrière-plan tels que des analyses.
Pour détecter la navigation dans les pages, vous devez comparer le [request URL]
au [request mainDocumentURL]
.
Cette solution fonctionnera dans tous les cas:
- (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;
}
}
Dans mon cas, je veux m'assurer que tout dans la vue Web ouvre Safari sauf le chargement initial et que j'utilise donc ...
- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if(inType != UIWebViewNavigationTypeOther) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
}
Note de rejet de l'application:
Enfin UIWbView
est mort et Apple ne l'acceptera plus.
Apple a commencé à envoyer un courrier électronique à tous les propriétaires d'applications qui utilisent toujours UIWebView
:
Utilisation obsolète des API - Apple cessera d'accepter les soumissions d'applications utilisant les API UIWebView
.
Apple prend la confidentialité des utilisateurs très au sérieux et il est évident qu’ils ne permettent pas la visualisation Web non sécurisée .
Alors, supprimez UIWebView de votre application dès que possible. N'utilisez pas essayez d'utiliser UIWebView
dans la nouvelle application créée et je préfère utiliser WKWebView
si possible