Bitte aktualisieren Sie die richtige Antwort markiert
Efren
Antworten:
184
Meine Lösung besteht darin, die Navigation abzubrechen und die Anforderung erneut mit loadRequest zu laden. Dies wird das ähnliche Verhalten wie UIWebView sein, das im aktuellen Frame immer ein neues Fenster öffnet.
Implementieren Sie den WKUIDelegateDelegaten und setzen Sie ihn auf _webview.uiDelegate. Dann implementieren Sie:
Dies ist die richtige Antwort. Wir haben die akzeptierte Antwort ohne Erfolg versucht. Aber die Antwort von @ Cloud funktioniert, und diese Antwort in den Entwicklerforen erklärt, warum.
Christopher Pickslay
5
Diese Lösung hat bei mir funktioniert. Vergessen Sie nicht, die UIDelegateEigenschaft festzulegen, da diese Methode in WKUIDelegatenot deklariert ist WKNavigationDelegate.
Taketo Sano
1
Ok, ich sehe, dass die Leute das WKWebView so nutzen wollen. Ich habe die Möglichkeit, target = _blank-Links in derselben WKWebView (wie oben gezeigt) in meinem Projekt github.com/sticksen/STKWebKitViewController zu öffnen .
Stk
5
@ChristopherPickslay Bei Verwendung dieser Methode mit meinem WKWebView ist die Anforderungs-URL immer leer, sodass die Webansicht auf eine leere weiße Seite verweist. Irgendwelche Ideen?
Jason Murray
1
Wenn die '_blank'-Anfrage von einem Formular mit Postdaten gesendet wird, finde ich, dass die Postdaten verloren gehen !!! Irgendeine Hilfe? @ Cloud Wu
Andrew
66
Die Antwort von @Cloud Xu ist die richtige Antwort. Nur als Referenz, hier ist es in Swift:
// this handles target=_blank links by opening them in the same view
func webView(webView:WKWebView!, createWebViewWithConfiguration configuration:WKWebViewConfiguration!, forNavigationAction navigationAction:WKNavigationAction!, windowFeatures:WKWindowFeatures!)->WKWebView!{if navigationAction.targetFrame ==nil{
webView.loadRequest(navigationAction.request)}returnnil}
Wie würden Sie es schreiben, wenn Sie möchten, dass es stattdessen in Safari geöffnet wird? Worauf muss ich im View Controller verweisen, damit dies funktioniert?
Jed Grant
1
Um die neue Seite in der mobilen Safari zu öffnen, lesen
Paul Bruneau
1
Dies funktioniert für Links, scheint aber keine neuen Fenster zu erkennen, die mit JavaScript geöffnet wurden, dh window.open (url, "_blank")
Crashalot
FYI webView.loadRequest wurde offenbar in neueren Versionen der API in webView.load umbenannt
Bill Weinman
52
So verwenden Sie die neueste Version von Swift 4.2+
Kein echtes Duplikat. Es gibt Unterschiede in der Optionalität der Parameter, die nicht mit dem Swift 4.1 WKUIDelegate-Protokoll in der von Ihnen verknüpften Antwort übereinstimmen.
Yakattack
Hallo, als ich WKWebview mit Pinterest URL geladen habe, konnte ich "Weiter mit Facebook" nicht öffnen. Jetzt kann ich auf "Continuew with Google" klicken und die Informationen abrufen. Hilf mir bitte.
Nrv
Ich habe das gleiche Problem mit wkwebview; Login und Weiterleitung funktionierten in meiner App nicht. Irgendeine Hilfe ?
Jamshed Alam
1
Bitte jeder kann mir helfen, ich habe Delegierten uiDelegate zu wkwebview zugewiesen, aber seine Methode zum Erstellen einer Webansicht mit Konfiguration wird nicht aufgerufen
Chetan Panchal
25
Fügen Sie sich als WKNavigationDelegate hinzu
_webView.navigationDelegate =self;
und implementieren Sie den folgenden Code im Delegaten-Rückruf entscheidendPolicyForNavigationAction: entscheidungshandler:
-(void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler
{//this is a 'new window action' (aka target="_blank") > open this URL externally. If we´re doing nothing here, WKWebView will also just do nothing. Maybe this will change in a later stage of the iOS 8 Betaif(!navigationAction.targetFrame){
NSURL *url = navigationAction.request.URL;UIApplication*app =[UIApplication sharedApplication];if([app canOpenURL:url]){[app openURL:url];}}
decisionHandler(WKNavigationActionPolicyAllow);}
PS: Dieser Code stammt aus meinem kleinen Projekt STKWebKitViewController, das eine verwendbare Benutzeroberfläche um WKWebView herum umschließt.
Es gibt einen Tippfehler. Ein Punkt fehlt zwischen WKNavigationActionPolicy und Allow
Huhn
@stk Wie kann ich verstehen, ob UIApplication einen Link in der Safari-App öffnen wird? Wenn es sich um einen Appstore-Link handelt - ich muss ot in der Appstore-App öffnen, aber wenn es sich um eine übliche Webseite handelt - muss ich ihn in derselben WKWebView stackoverflow.com/questions/29056854/… öffnen
BergP
1
@LeoKoppelkamm Es ist kein Tippfehler, sondern Objective-C, nicht Swift. ;)
Ayan Sengupta
1
Dies funktioniert für Links, scheint aber keine neuen Fenster zu erkennen, die mit JavaScript geöffnet wurden, dhwindow.open(url, "_blank")
Crashalot
@Crashalot Haben Sie die Lösung für window.open gefunden?
Sam
14
Wenn Sie das WKWebView.navigationDelegate bereits festgelegt haben
WKWebView.navigationDelegate = self;
Sie müssen nur implementieren:
-(void)webView:(WKWebView*)webView decidePolicyForNavigationAction:(WKNavigationAction*)navigationAction decisionHandler:(void(^)(WKNavigationActionPolicy))decisionHandler
{
BOOL shouldLoad =[self shouldStartLoadWithRequest:navigationAction.request];// check the url if necessaryif(shouldLoad && navigationAction.targetFrame ==nil){// WKWebView ignores links that open in new window[webView loadRequest:navigationAction.request];}// always pass a policy to the decisionHandler
decisionHandler(shouldLoad ?WKNavigationActionPolicyAllow:WKNavigationActionPolicyCancel);}
Auf diese Weise müssen Sie die WKUIDelegate-Methode nicht implementieren.
Ich bestätige, dass der Swift-Code von Bill Weinman korrekt ist. Aber ich muss erwähnen, dass Sie auch UIDelegate delegieren müssen, damit es funktioniert, falls Sie neu in der iOS-Entwicklung wie ich sind.
Etwas wie das:
self.webView?.UIDelegate=self
Es gibt also drei Stellen, an denen Sie Änderungen vornehmen müssen.
Ich bin mir nicht sicher, ob dies impliziert ist, aber damit diese Codezeile in iOS 10 funktioniert, müssen Sie ViewControllersie erben WKUIDelegate. dhclass ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate
ltrainpr
4
Sie können auch einen anderen Ansichts-Controller drücken oder eine neue Registerkarte öffnen usw.:
Ist es notwendig einzustellen vc.url? Ich stelle es nicht ein und die Webansicht wird ordnungsgemäß geladen. Außerdem sehe ich meiner Erfahrung nach nur createWebViewWithConfigurationangerufen, wenn es navigationAction.targetFrameist nil. Können Sie ein Szenario beschreiben, in dem dies nicht der Fall wäre?
Mason G. Zhwiti
@ MasonG.Zhwiti Ich habe WKWebViews im letzten Herbst aktiv für ein Projekt verwendet, aber seitdem nichts mehr damit gemacht - daher kann ich Ihre Frage wirklich nicht beantworten. Zu der Zeit, als ich das oben Gesagte gepostet habe, hat es funktioniert. Ich kann mir nicht vorstellen, wie es funktioniert, ohne die vc.url einzustellen.
David H
Ich denke, es funktioniert ohne, weil Sie die von Ihnen erstellte Webansicht zurückgeben, und dann (ich vermute), was auch immer Sie zum Erstellen aufgefordert hat, wird die Webansicht zum Laden der betreffenden URL verwendet.
Hallo, wie kann ich nach dem Login mit Facebook das Freigabefenster für Facebook Share auf ähnliche Weise öffnen? Ich habe mich mit dem Erstellen einer neuen wkwebview angemeldet, jetzt ist der Benutzer angemeldet. Wie kann ich nun das Freigabefenster verfolgen?
Wie Sie sehen können, öffnen wir hier nur eine neue webViewmit der neuen URL und steuern die Möglichkeit des Schließens, nur wenn Sie eine Antwort darauf benötigen second webview, die auf der ersten angezeigt wird.
Ich bin auf einige Probleme gestoßen, die nicht einfach mit gelöst werden können webView.load(navigationAction.request). Also erstelle ich ein neues WebView und es funktioniert einwandfrei.
**Use following function to create web view**
func initWebView(configuration:WKWebViewConfiguration){let webView =WKWebView(frame:UIScreen.main.bounds, configuration: configuration)
webView.uiDelegate =self
webView.navigationDelegate =self
view.addSubview(webView)self.webView = webView
}**InViewDidLoad:**if webView ==nil{ initWebView(configuration:WKWebViewConfiguration())}
webView?.load(url: url1)**WKUIDelegateMethod need to be implemented**
extension WebViewController:WKUIDelegate{
func webView(_ webView:WKWebView, createWebViewWith configuration:WKWebViewConfiguration,for navigationAction:WKNavigationAction, windowFeatures:WKWindowFeatures)->WKWebView?{// push new screen to the navigation controller when need to open url in another "tab"print("url:\(String(describing: navigationAction.request.url?.absoluteString))")iflet url = navigationAction.request.url, navigationAction.targetFrame ==nil{let viewController =WebViewController()
viewController.initWebView(configuration: configuration)
viewController.url1 = url
DispatchQueue.main.async{[weak self]inself?.navigationController?.pushViewController(viewController, animated:true)}return viewController.webView
}returnnil}}
extension WKWebView{
func load(url: URL){ load(URLRequest(url: url))}}
Antworten:
Meine Lösung besteht darin, die Navigation abzubrechen und die Anforderung erneut mit loadRequest zu laden. Dies wird das ähnliche Verhalten wie UIWebView sein, das im aktuellen Frame immer ein neues Fenster öffnet.
Implementieren Sie den
WKUIDelegate
Delegaten und setzen Sie ihn auf_webview.uiDelegate
. Dann implementieren Sie:quelle
UIDelegate
Eigenschaft festzulegen, da diese Methode inWKUIDelegate
not deklariert istWKNavigationDelegate
.Die Antwort von @Cloud Xu ist die richtige Antwort. Nur als Referenz, hier ist es in Swift:
quelle
So verwenden Sie die neueste Version von Swift 4.2+
Erweitern Sie Ihre Klasse mit WKUIDelegate
Festlegen des Delegaten für die Webansicht
Protokollmethode implementieren
quelle
Fügen Sie sich als WKNavigationDelegate hinzu
und implementieren Sie den folgenden Code im Delegaten-Rückruf entscheidendPolicyForNavigationAction: entscheidungshandler:
PS: Dieser Code stammt aus meinem kleinen Projekt
STKWebKitViewController
, das eine verwendbare Benutzeroberfläche um WKWebView herum umschließt.quelle
window.open(url, "_blank")
Wenn Sie das WKWebView.navigationDelegate bereits festgelegt haben
WKWebView.navigationDelegate = self;
Sie müssen nur implementieren:
Auf diese Weise müssen Sie die WKUIDelegate-Methode nicht implementieren.
quelle
Keine dieser Lösungen hat bei mir funktioniert. Ich habe das Problem gelöst durch:
1) Implementierung von WKUIDelegate
2) Festlegen des UIDelegate-Delegaten von wkWebview
3) Implementieren der Methode createWebViewWithConfiguration
quelle
Cloud xu
Die Antwort löst mein Problem.Falls jemand die entsprechende Swift-Version (4.x / 5.0) benötigt, hier ist sie:
Natürlich muss man
webView.uiDelegate
zuerst einstellen .quelle
Ich bestätige, dass der Swift-Code von Bill Weinman korrekt ist. Aber ich muss erwähnen, dass Sie auch UIDelegate delegieren müssen, damit es funktioniert, falls Sie neu in der iOS-Entwicklung wie ich sind.
Etwas wie das:
Es gibt also drei Stellen, an denen Sie Änderungen vornehmen müssen.
quelle
self.webView.UIDelegate = self
ViewController
sie erbenWKUIDelegate
. dhclass ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate
Sie können auch einen anderen Ansichts-Controller drücken oder eine neue Registerkarte öffnen usw.:
quelle
vc.url
? Ich stelle es nicht ein und die Webansicht wird ordnungsgemäß geladen. Außerdem sehe ich meiner Erfahrung nach nurcreateWebViewWithConfiguration
angerufen, wenn esnavigationAction.targetFrame
istnil
. Können Sie ein Szenario beschreiben, in dem dies nicht der Fall wäre?Basierend auf Allen Huang Antwort
Einzelheiten
Ziele
target=“_blank”
push
View Controller mit WebView, wenn der aktuelle Controller hatnavigationController
present
View Controller mit WebView in allen anderen FällenLösung
Vollständige Probe
Fügen Sie Ihre Info.plist-Transportsicherheitseinstellung hinzu
Storyboards
Version 1
Version 2
quelle
Das hat bei mir funktioniert:
Wie Sie sehen können, öffnen wir hier nur eine neue
webView
mit der neuen URL und steuern die Möglichkeit des Schließens, nur wenn Sie eine Antwort darauf benötigensecond webview
, die auf der ersten angezeigt wird.quelle
Ich bin auf einige Probleme gestoßen, die nicht einfach mit gelöst werden können
webView.load(navigationAction.request)
. Also erstelle ich ein neues WebView und es funktioniert einwandfrei.quelle
quelle