从WebView跳到普通View

本文转载至 http://pingguohe.net/2011/06/25/webview_to_nativeview/

做网络ios应用难免要用到UIWebViewController,直接嵌入一个html页面。这种native+web的方式再很多app中都有应用,app store就是一个,另外如淘宝iPhone客户端的支付,口碑网iPhone客户端的团购内容,等等。这种实现方式,某种程度上牺牲了一些体验,但大大提高了开发效率,而且降低了升级成本。这种方式非常适合实现一个仍处在发展初期的功能。

但使用native+web的方式有一个最大的问题,就是从WebView向NativeView的跳转。由于进入WebView后,页面中的链接都是web控制,所有点击都将在web框架内进行,无法返回到NativeView,给WebView的使用造成很大局限。这里介绍一下如何实现从WebView向NativeView的跳转。

实现原理很简单,在内嵌的页面里写一个规定格式的超链接,在WebViewController里抓载入状态,判断URL是否为约定的,按照约定跳转到相应的NativeView。

具体实现,先看WebViewDelegate里的几个方法:

- (BOOL)webView:(UIWebView *)webView
   shouldStartLoadWithRequest:(NSURLRequest *)request
   navigationType:(UIWebViewNavigationType)navigationType;
 
- (void)webViewDidStartLoad:(UIWebView *)webView;
 
- (void)webViewDidFinishLoad:(UIWebView *)webView;
 
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;

这四个方法分别在不同时机被调用。第一个方法在页面请求发出之前被调用,第二个和第三个方法分别再页面内容开始载入和载入完成时被调用,最后一个是载入失败时被调用。

要抓请求状态需要在第一个方法中。因为页面中所写的URL是应用开发者约定的格式,而不是HTTP请求,因此这个请求无法成功发送,那么也就不会调用到第二和第三个方法,第四个方法用于异常处理,所以只能在第一个方法中抓请求状态。通过第一个方法的request参数,拿到request.URL,这个URL就是我们写在WebView上的,那么WebViewController就可以根据约定,判断出要跳转的NativeView,通过NavigationController跳转,或是实现其他逻辑。

在约定URL的时候还要注意,这个URL一定不要定义成一个HTTP请求。WebViewController就会自动处理HTTP请求,把请求发出去,页面也会发生重新载入,而这个请求是指向NativeView的,也就是不存在与Internet上,所以页面将出现404状态。

另外,如果WebView上指向NativeView的不是一个超链接,通过javascript方式也可以实现这个功能。只要通过JS把页面跳转到之前提到过的约定格式的URL就可以了。通过JS的方式,还可以实现WebView到NativeView的自动跳转。

—— Jul. 4, 2011 ——

附送把URL拆解的代码一份

ExtString.h

 
#define PROTOCOL	@"PROTOCOL"
#define HOST		@"HOST"
#define PARAMS		@"PARAMS"
#define URI			@"URI"
 
@interface ExtNSString : NSString {
}
 
@end
 
@interface NSString (ExtNSString)
 
/**
 *  @param NSString *URL 需要解析的URL,格式如:http://host.name/testpage/?keyA=valueA&keyB=valueB
 *  @return NSDictionary *params 从URL中解析出的参数表
 *    PROTOCOL 如 http
 *    HOST     如 host.name
 *    PARAMS   如 {keyA:valueA, keyB:valueB}
 *    URI      如 /testpage
 */
- (NSDictionary *)paramsFromURL;
 
@end

ExtString.m

#import "ExtNSString.h"
 
@implementation NSString (ExtNSString)
 
- (NSDictionary *)paramsFromURL {
 
	NSString *protocolString = [self substringToIndex:([self rangeOfString:@"://"].location)];
 
	NSString *tmpString = [self substringFromIndex:([self rangeOfString:@"://"].location + 3)];
	NSString *hostString = nil;
 
	if (0 < [tmpString rangeOfString:@"/"].length) {
		hostString = [tmpString substringToIndex:([tmpString rangeOfString:@"/"].location)];
	}
	else if (0 < [tmpString rangeOfString:@"?"].length) {
		hostString = [tmpString substringToIndex:([tmpString rangeOfString:@"?"].location)];
	}
	else {
		hostString = tmpString;
	}
 
	tmpString = [self substringFromIndex:([self rangeOfString:hostString].location + [self rangeOfString:hostString].length)];
	NSString *uriString = @"/";
	if (0 < [tmpString rangeOfString:@"/"].length) {
		if (0 < [tmpString rangeOfString:@"?"].length) {
			uriString = [tmpString substringToIndex:[tmpString rangeOfString:@"?"].location];
		}
		else {
			uriString = tmpString;
		}
	}
 
	NSMutableDictionary* pairs = [NSMutableDictionary dictionary];
	if (0 < [self rangeOfString:@"?"].length) {
		NSString *paramString = [self substringFromIndex:([self rangeOfString:@"?"].location + 1)];
		NSCharacterSet* delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&;"];
		NSScanner* scanner = [[[NSScanner alloc] initWithString:paramString] autorelease];
		while (![scanner isAtEnd]) {
			NSString* pairString = nil;
			[scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString];
			[scanner scanCharactersFromSet:delimiterSet intoString:NULL];
			NSArray* kvPair = [pairString componentsSeparatedByString:@"="];
			if (kvPair.count == 2) {
				NSString* key = [[kvPair objectAtIndex:0]
								 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
				NSString* value = [[kvPair objectAtIndex:1]
								   stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
				[pairs setObject:value forKey:key];
			}
		}
	}
 
	return [NSDictionary dictionaryWithObjectsAndKeys:
			pairs, PARAMS,
			protocolString, PROTOCOL,
			hostString, HOST,
			uriString, URI, nil];
}
 
@end
 
@implementation ExtNSString
@end
时间: 2024-08-27 23:41:34

从WebView跳到普通View的相关文章

H5(WebView)跳Native(UIView)

做网络ios应用难免要用到UIWebViewController,直接嵌入一个html页面.这种native+web的方式再很多app中都有应用,app store就是一个,另外如淘宝iPhone客户端的支付,口碑网iPhone客户端的团购内容,等等.这种实现方式,某种程度上牺牲了一些体验,但大大提高了开发效率,而且降低了升级成本.这种方式非常适合实现一个仍处在发展初期的功能. 但使用native+web的方式有一个最大的问题,就是从WebView向NativeView的跳转.由于进入WebVi

android webview ZoomButtonsController 导致android.view.WindowLeaked 问题彻底解决

Activity has leaked window android.widget.ZoomButtonsController that was originally added here android.view.WindowLeaked: 引起这个错误的原因是: 发现是webview的 ZoomButton,也就是那两个放大和缩小的按钮,导致的.如果设置为让他们出现,并且可以自动隐藏,那么,由于他们的自动隐藏是一个渐变的过程,所以在逐渐消失的过程中如果调用了父容器的destroy方法,就会导

用mpvue写微信小程序时,webview跳转外部链接,再跳转回来需要点两次返回箭头才能跳转

问题描述: 给公司做微信小程序时遇到了这个问题,用mpvue框架搭建的小程序,从首页点击进去,先跳转到一个中间页面,在中间页面放上webview链接到外部的H5页面,这时点击小程序左上角自带的返回按钮,第一次会跳转到空白页,再点一次才能跳转到首页. 首页: 详情页: 这时需要点击左上角的返回箭头两次,才能跳转到首页 解决办法: 小程序跳到外部页面方法: 1.从首页(index)跳转到中间页(template): goPage(id){ wx.navigateTo({url:'../templat

JavaScript如何在webView跳转到指点的位置

1 //当完成webView加载时调用 2 - (void)webViewDidFinishLoad:(UIWebView *)webView{ 3 4 //如果有id 5 if (self.help.Id) { 6 //取得模型对应的id 7 NSString *js = [NSString stringWithFormat:@"window.location.href ='#%@'",self.help.Id]; 8 [webView stringByEvaluatingJavaS

最简单webview跳转

String url = "http://www.qq.com" Uri uri=Uri.parse("http://www.baidu.com"); Intent intent=new Intent(Intent.ACTION_VIEW, uri); startActivity(intent);

uniapp webview 跳回小程序 填坑

h5配置里面配置下index  不懂的话点  后面的参考 看官方提示 然后index.html里面引入微信的jssdk <script src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js" type="text/javascript" charset="utf-8"></script> //wx.换成jWeixin. jWeixin.miniProgram.getEnv(

WebView使用详解(三)——WebChromeClient与LoadData补充

前言: 我不会忘了我 忘了我曾说过一定会得到的梦想 --<老大>小柯 相关文章 1.<WebView使用详解(一)--Native与JS相互调用(附JadX反编译)> 2.<WebView使用详解(二)--WebViewClient与常用事件监听> 一.WebChromeClient 1.概述 (1). 与WebViewClient的区别 很多同学一看到这里有Chrome,立马就会想到google 的Chrome浏览器:这里并不是指Chrome浏览器的意思,而是泛指浏览

(转)完美解决 Android WebView 文本框获取焦点后自动放大有关问题

完美解决 Android WebView 文本框获取焦点后自动放大问题 前几天在写一个项目时,要求在项目中嵌入一个WebView 本来很快就完成了,测试也没有问题.但发给新加坡时,他们测试都会出现文本框聚焦时,网页面会放大(他们用三星手机测试的) 网上查了好久参考他的方法加上去测试 http://www.cppblog.com/guojingjia2006/archive/2012/12/18/196429.html 下面我将原文copy过来 **************************

【转】WebView的JavaScript与本地代码三种交互方式

WebView的漏洞分析 漏洞产生的原因 最近在开发过程中遇到一个问题,就是 WebView 使用的时候,还是需要解决之前系统(4.2之前)导致的一个漏洞,虽然现在这个系统版本用户很少了,但是也不能忽视,关于这个漏洞,这里就不多做解释了,可能有的同学早就了解了,本来想写一篇文章详细介绍一下,但是网上的知识太多了,而且都很详细,就没弄了,这里大致简单明了的说几句: 漏洞产生的原因 这个漏洞导致的原因主要是因为Android中 WebView 中的 JS访问本地方法 的方式存在缺陷,我们做过交互的都