Mi solución es cancelar la navegación y cargar la solicitud con loadRequest: nuevamente. Esto vendrá con un comportamiento similar como UIWebView que siempre abre una nueva ventana en el marco actual.
Implemente el WKUIDelegatedelegado y configúrelo en _webview.uiDelegate. Luego implemente:
Esta es la respuesta correcta. Probamos la respuesta aceptada sin éxito. Pero la respuesta de @ Cloud funciona, y esta respuesta en los foros de desarrollo explica por qué.
Christopher Pickslay
5
Esta solución funcionó para mí. No olvide establecer la UIDelegatepropiedad, ya que este método se declara en WKUIDelegatenot WKNavigationDelegate.
Taketo Sano
1
Ok, veo que la gente quiere usar WKWebView de esta manera. Implementé la posibilidad de abrir target = _blank-Links en el mismo WKWebView (como se muestra arriba) en mi proyecto github.com/sticksen/STKWebKitViewController .
stk
5
@ChristopherPickslay cuando se usa este método con mi WKWebView, la URL de solicitud siempre está en blanco, por lo que la vista web dirige a una página en blanco en blanco, ¿alguna idea?
Jason Murray
1
Cuando la solicitud '_blank' se envía desde un formulario con datos de publicación, ¡encuentro que los datos de publicación se perderán! ¿Alguna ayuda? @Cloud Wu
Andrew
66
La respuesta de @Cloud Xu es la respuesta correcta. Solo como referencia, aquí está en 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}
No es un duplicado real. Hay diferencias en la opcionalidad de los parámetros que no se ajustan al protocolo Swift 4.1 WKUIDelegate en la respuesta a la que se vinculó.
yakattack
Hola, Cuando estoy cargando WKWebview con la URL de Pinterest, no pude abrir "Continuar con Facebook". Ahora puedo hacer clic y obtener la información sobre "Continuar con Google". Ayúdame por favor.
Nrv
Estoy enfrentando el mismo problema con wkwebview; iniciar sesión y redireccionar no funcionó en mi aplicación. Alguna ayuda ?
Jamshed Alam
1
por favor, cualquiera puede ayudarme, he asignado el delegado uiDelegate a wkwebview pero su método de creación de vista web con configuración no está siendo llamado
chetan panchal
25
Agréguese como WKNavigationDelegate
_webView.navigationDelegate =self;
e implementar el siguiente código en la devolución de llamada delegada decidePolicyForNavigationAction: decisionHandler:
-(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);}
PD: Este código es de mi pequeño proyecto STKWebKitViewController, que envuelve una interfaz de usuario utilizable alrededor de WKWebView.
Hay un error tipográfico. Falta un punto entre WKNavigationActionPolicy y Allow
pollo
@stk ¿Cómo puedo saber si UIApplication va a abrir un enlace en la aplicación Safari? Si es un enlace de Appstore, necesito abrir ot en la aplicación Appstore, pero si es una página web habitual, necesito abrirlo en el mismo WKWebView stackoverflow.com/questions/29056854/…
BergP
1
@LeoKoppelkamm No es un error tipográfico sino que es Objective-C, no Swift. ;)
Ayan Sengupta
1
Esto funciona para enlaces, pero no parece detectar nuevas ventanas abiertas con JavaScript, es decir,window.open(url, "_blank")
Crashalot
@Crashalot ¿Encontraste la solución para window.open?
Sam
14
Si ya ha configurado WKWebView.navigationDelegate
WKWebView.navigationDelegate = self;
solo necesitas implementar:
-(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);}
de esta forma no es necesario implementar el método WKUIDelegate.
Confirmo que el código Swift de Bill Weinman es correcto. Pero debo mencionar que también debe delegar UIDelegate para que funcione, en caso de que sea nuevo en el desarrollo de iOS como yo.
Algo como esto:
self.webView?.UIDelegate=self
Entonces, hay tres lugares en los que necesita realizar cambios.
Escriba su código, es:self.webView.UIDelegate = self
Henrik Petterson
No estoy seguro si está implícito, pero para que esta línea de código funcione en iOS 10, ViewControllerdebe heredar WKUIDelegate. ieclass ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate
ltrainpr
4
También puede presionar otro controlador de vista o abrir una nueva pestaña, etc.
¿Es necesario configurar vc.url? No lo estoy configurando y la vista web se está cargando correctamente. Además, en mi experiencia, solo veo que se createWebViewWithConfigurationllama cuando navigationAction.targetFramees nil. ¿Puede describir un escenario en el que esto no sería cierto?
Mason G. Zhwiti
@ MasonG.Zhwiti Estaba usando activamente WKWebViews para un proyecto el otoño pasado, pero desde entonces no he hecho nada con ellos, así que realmente no puedo responder a su pregunta. En el momento en que publiqué lo anterior, funcionó. Sin embargo, no puedo comprender cómo funciona sin configurar vc.url.
David H
Creo que funciona sin porque está devolviendo la vista web que creó, y luego (supongo) lo que sea que le haya pedido que la cree se encarga de usar la vista web para cargar la URL en cuestión.
hola, después de iniciar sesión con facebook, ¿cómo abrir la ventana de compartir para compartir en facebook de manera similar? He iniciado sesión con la creación de un nuevo wkwebview, ahora el usuario ha iniciado sesión. Ahora, ¿cómo realizar un seguimiento de la ventana compartida?
Como puede ver, lo que hacemos aquí es simplemente abrir una nueva webViewcon la nueva URL y controlar la posibilidad de que se cierre, solo si necesita una respuesta de eso second webviewpara que se muestre en la primera.
Encontré algunos problemas que no se pueden resolver con solo usar webView.load(navigationAction.request). Así que uso crear un nuevo webView para hacer y funciona bien.
**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))}}
Respuestas:
Mi solución es cancelar la navegación y cargar la solicitud con loadRequest: nuevamente. Esto vendrá con un comportamiento similar como UIWebView que siempre abre una nueva ventana en el marco actual.
Implemente el
WKUIDelegate
delegado y configúrelo en_webview.uiDelegate
. Luego implemente:fuente
UIDelegate
propiedad, ya que este método se declara enWKUIDelegate
notWKNavigationDelegate
.La respuesta de @Cloud Xu es la respuesta correcta. Solo como referencia, aquí está en Swift:
fuente
Para usar la última versión de Swift 4.2+
Amplíe su clase con WKUIDelegate
Establecer delegado para vista web
Implementar el método de protocolo
fuente
Agréguese como WKNavigationDelegate
e implementar el siguiente código en la devolución de llamada delegada decidePolicyForNavigationAction: decisionHandler:
PD: Este código es de mi pequeño proyecto
STKWebKitViewController
, que envuelve una interfaz de usuario utilizable alrededor de WKWebView.fuente
window.open(url, "_blank")
Si ya ha configurado WKWebView.navigationDelegate
WKWebView.navigationDelegate = self;
solo necesitas implementar:
de esta forma no es necesario implementar el método WKUIDelegate.
fuente
Ninguna de esas soluciones funcionó para mí, resolví el problema de la siguiente manera:
1) Implementación de WKUIDelegate
2) Configuración del delegado UIDelegate de wkWebview
3) Implementar el método createWebViewWithConfiguration
fuente
Cloud xu
La respuesta resuelve mi problema.En caso de que alguien necesite la versión equivalente de Swift (4.x / 5.0), aquí está:
Por supuesto,
webView.uiDelegate
primero debes configurarlo .fuente
Confirmo que el código Swift de Bill Weinman es correcto. Pero debo mencionar que también debe delegar UIDelegate para que funcione, en caso de que sea nuevo en el desarrollo de iOS como yo.
Algo como esto:
Entonces, hay tres lugares en los que necesita realizar cambios.
fuente
self.webView.UIDelegate = self
ViewController
debe heredarWKUIDelegate
. ieclass ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate
También puede presionar otro controlador de vista o abrir una nueva pestaña, etc.
fuente
vc.url
? No lo estoy configurando y la vista web se está cargando correctamente. Además, en mi experiencia, solo veo que secreateWebViewWithConfiguration
llama cuandonavigationAction.targetFrame
esnil
. ¿Puede describir un escenario en el que esto no sería cierto?Basado en la respuesta de Allen Huang
Detalles
Objetivos
target=“_blank”
push
Ver controlador con webView si el controlador actual tienenavigationController
present
Ver controlador con webView en todos los demás casosSolución
Muestra completa
agregue su configuración de seguridad de transporte Info.plist
Guiones gráficos
Versión 1
Versión 2
fuente
Esto funcionó para mí:
Como puede ver, lo que hacemos aquí es simplemente abrir una nueva
webView
con la nueva URL y controlar la posibilidad de que se cierre, solo si necesita una respuesta de esosecond webview
para que se muestre en la primera.fuente
Encontré algunos problemas que no se pueden resolver con solo usar
webView.load(navigationAction.request)
. Así que uso crear un nuevo webView para hacer y funciona bien.fuente
fuente