app - webview ios swift




Liens ouverts UIWebView dans Safari (6)

Ajoutez ceci au délégué UIWebView:

(édité pour vérifier le type de navigation, vous pouvez aussi passer par file:// demandes 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
}

Mettre à jour

Comme openURL a été déprécié 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;
}

J'ai un UIWebView très simple avec le contenu de mon ensemble d'applications. Je souhaite que tous les liens de la vue Web s'ouvrent dans Safari plutôt que dans la vue Web. Est-ce possible?


Dans Swift, vous pouvez utiliser le code suivant:

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
    }
}

Assurez-vous de vérifier la valeur de l'URL et le type de navigation.


Les autres réponses ont un problème: elles reposent sur l'action que vous faites et non sur le lien lui-même pour décider si vous voulez le charger dans Safari ou dans Webview.

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 des liens externes dans Safari, et non des liens internes. Dans ce cas, vérifiez la propriété URL.host de votre requête.

J'utilise ce morceau de code pour vérifier si j'ai un nom d'hôte dans l'URL qui est en cours d'analyse, ou si elle est intégrée 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; 
    }
}

Vous pouvez bien sûr adapter l'expression régulière à vos besoins.


Si quelqu'un se demande, la solution de Drawnonward ressemblerait à 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
}

Voici l'équivalent Xamarin iOS de la réponse de 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;
    }
}

La réponse acceptée ne fonctionne pas.

Si votre page charge des URL via Javascript, le type de navigationType sera UIWebViewNavigationTypeOther . Qui, malheureusement, inclut également des charges de page d'arrière-plan telles que des analyses.

Pour détecter la navigation dans les pages, vous devez comparer [request URL] à [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;
    }
}




mobile-safari