ios - que - Enlaces abiertos de UIWebView en Safari
uiwebview que es (8)
Tengo un UIWebView muy simple con contenido de mi paquete de aplicaciones. Me gustaría que los enlaces en la vista web se abran en Safari en lugar de en la vista web. es posible?
Agregue esto al delegado de UIWebView:
(editado para verificar el tipo de navegación. También puede pasar a través del file://
solicitudes que serían enlaces relativos)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked ) {
[[UIApplication sharedApplication] openURL:[request URL]];
return NO;
}
return YES;
}
Versión rápida:
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.LinkClicked {
UIApplication.sharedApplication().openURL(request.URL!)
return false
}
return true
}
Versión Swift 3:
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if navigationType == UIWebViewNavigationType.linkClicked {
UIApplication.shared.openURL(request.url!)
return false
}
return true
}
Actualizar
Como openURL
ha quedado en desuso en 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;
}
Aquí está el equivalente de Xamarin iOS de la respuesta 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;
}
}
En Swift puedes usar el siguiente código:
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
}
}
Asegúrese de verificar el valor de la URL y el tipo de navegación.
En mi caso, quiero asegurarme de que absolutamente todo en la vista web abre Safari, excepto la carga inicial, y por eso uso ...
- (BOOL)webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if(inType != UIWebViewNavigationTypeOther) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
}
Las otras respuestas tienen un problema: dependen de la acción que realice y no del enlace en sí para decidir si cargarlo en Safari o en la vista web.
Ahora, a veces esto es exactamente lo que quieres, lo cual está bien; pero otras veces, especialmente si tiene enlaces de anclaje en su página, realmente desea abrir solo enlaces externos en Safari, y no los internos. En ese caso, debe verificar la propiedad URL.host
de su solicitud.
Utilizo ese fragmento de código para comprobar si tengo un nombre de host en la URL que se está analizando, o si está incrustado en 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;
}
}
Por supuesto, puede adaptar la expresión regular para que se ajuste a sus necesidades.
Si alguien se pregunta, la solución de Drawnonward se vería así en 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 comentario rápido a la respuesta del usuario 306253: precaución con esto, cuando intente cargar algo en UIWebView (es decir, incluso desde el código), este método evitará que suceda.
Lo que puedes hacer para prevenir esto (gracias Wade) es:
if (inType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
Es posible que también desee controlar los tipos UIWebViewNavigationTypeFormSubmitted
y UIWebViewNavigationTypeFormResubmitted
.
La respuesta aceptada no funciona.
Si su página carga direcciones URL a través de Javascript, el tipo de navigationType
será UIWebViewNavigationTypeOther
. Lo cual, desafortunadamente, también incluye cargas de páginas de fondo, tales como análisis.
Para detectar la navegación de la página, debe comparar la [request URL]
con la [request mainDocumentURL]
.
Esta solución funcionará en todos los casos:
- (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;
}
}