Ich habe eine sehr einfache UIWebView mit Inhalten aus meinem Anwendungspaket. Ich möchte, dass alle Links in der Webansicht in Safari anstatt in der Webansicht geöffnet werden. Ist das möglich?
Ich habe eine sehr einfache UIWebView mit Inhalten aus meinem Anwendungspaket. Ich möchte, dass alle Links in der Webansicht in Safari anstatt in der Webansicht geöffnet werden. Ist das möglich?
Antworten:
Fügen Sie dies dem UIWebView-Delegaten hinzu:
(bearbeitet, um nach dem Navigationstyp zu suchen. Sie können auch file://
Anfragen weiterleiten, die relative Links sind.)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
Schnelle Version:
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
}
Swift 4 Version:
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
}
Aktualisieren
Wie openURL
in iOS 10 veraltet:
- (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;
}
switch
für Aufzählungstypen vorzuziehen
Wenn sich jemand wundert, würde Drawnonwards Lösung in Swift so aussehen :
func webView(webView: UIWebView!, shouldStartLoadWithRequest request: NSURLRequest!, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
UIApplication.sharedApplication().openURL(request.URL)
return false
}
return true
}
UIWebViewDelegate
Ein kurzer Kommentar zur Antwort von user306253: Vorsicht, wenn Sie versuchen, etwas in die UIWebView selbst zu laden (dh sogar aus dem Code), verhindert diese Methode, dass dies geschieht.
Was Sie tun können, um dies zu verhindern (danke Wade), ist:
if (inType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
Möglicherweise möchten Sie auch die Typen UIWebViewNavigationTypeFormSubmitted
und behandeln UIWebViewNavigationTypeFormResubmitted
.
Die anderen Antworten haben ein Problem: Sie hängen von der Aktion ab, die Sie ausführen, und nicht vom Link selbst, um zu entscheiden, ob er in Safari oder in der Webansicht geladen werden soll.
Manchmal ist es genau das, was Sie wollen, was in Ordnung ist. In einigen anderen Fällen, insbesondere wenn Ihre Seite Ankerlinks enthält, möchten Sie in Safari wirklich nur externe und keine internen Links öffnen. In diesem Fall sollten Sie die URL.host
Eigenschaft Ihrer Anfrage überprüfen .
Ich verwende diesen Code, um zu überprüfen, ob ich einen Hostnamen in der URL habe, die analysiert wird, oder ob er in HTML eingebettet ist:
- (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;
}
}
Sie können den regulären Ausdruck natürlich an Ihre Bedürfnisse anpassen.
if (request.URL?.scheme != "file")
In Swift können Sie den folgenden Code verwenden:
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
}
}
Stellen Sie sicher, dass Sie nach dem URL-Wert und dem Navigationstyp suchen.
Hier ist das Xamarin iOS-Äquivalent zu Drawonwards Antwort.
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;
}
}
Die akzeptierte Antwort funktioniert nicht.
Wenn Ihre Seite URLs über Javascript lädt, ist dies der navigationType
Fall UIWebViewNavigationTypeOther
. Dies beinhaltet leider auch das Laden von Hintergrundseiten wie Analytics.
Zur Erkennung Seitennavigation, müssen Sie das vergleichen , [request URL]
um die[request mainDocumentURL]
.
Diese Lösung funktioniert in allen Fällen:
- (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;
}
}
App-Ablehnung Hinweis:
Schließlich UIWbView
ist es tot und Apple wird es nicht mehr akzeptieren.
Apple hat damit begonnen, E-Mails an alle App-Besitzer zu senden, die noch Folgendes verwenden UIWebView
:
Veraltete API-Nutzung - Apple akzeptiert keine Einsendungen von Apps mehr, die UIWebView
APIs verwenden.
Apple nimmt den Datenschutz der Benutzer sehr ernst und es ist offensichtlich, dass sie keine unsichere Webansicht zulassen .
Entfernen Sie UIWebView also so schnell wie möglich aus Ihrer App. Verwenden Sie nicht versuchen, UIWebView
in einer neu erstellten App zu verwenden, und ich bevorzuge die Verwendung, WKWebView
wenn möglich
ITMS-90809: Veraltete API-Nutzung - Apple akzeptiert keine Übermittlungen von Apps mehr, die UIWebView-APIs verwenden. Weitere Informationen finden Sie unter https://developer.apple.com/documentation/uikit/uiwebview .
Beispiel:
import UIKit
import WebKit
class WebInfoController: UIViewController,WKNavigationDelegate {
var webView : WKWebView = {
var webview = WKWebView()
return webview
}()
var _fileName : String!
override func viewDidLoad() {
self.view.addSubview(webView)
webView.fillSuperview()
let url = Bundle.main.url(forResource: _fileName, withExtension: "html")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
}
func webView(webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
print(error.localizedDescription)
}
func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
print("Strat to load")
}
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
print("finish to load")
}
}
In meinem Fall möchte ich sicherstellen, dass absolut alles in der Webansicht Safari außer dem anfänglichen Laden öffnet und ich verwende ...
- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if(inType != UIWebViewNavigationTypeOther) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
}