本文转载至 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

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

  1. 小程序webview跳转页面后没有返回按钮完美解决方案

    随着小程序越来越火爆,使一个产品如果只有公众号H5页面和APP显得不怎么完美,总感觉不搭上小程序这趟流量车,就会少了点什么,心里别扭地很.在此驱动下,我所在公司也决定赶紧上车. 但是,如果要按照小程序 ...

  2. WebView跳转到底部

    webview中有个computeVerticalScrollRange方法,是protected的,可以用反射,也可以自己写一个view继承webview,实现computeVerticalScro ...

  3. WebView in ScrollView:View not displayed because it is too large to fit into a software layer

    报错信息 W/View: WebView not displayed because it is too large to fit into a software layer (or drawing ...

  4. 如何处理webView跳转

    - (void)webView:(UIWebView *)wv didFailLoadWithError:(NSError *)error {    // Give iOS a chance to o ...

  5. jfinal取消默认跳转到view.jsp页面的方法

    今天为了在一个列表中添加一个删除的方法,直接在方法里面谢了一个dao.del();方法,但是调用的时候却出现404错误. 然后就写了一句下面的代码 redirect("/api/listMe ...

  6. iOS悬浮窗口(无论界面跳转、View始终在视图上显示,可移动)

    2016.09.24 23:52* 字数 71 阅读 5925评论 9喜欢 11 让所有界面都显示,最好还是封装一个继承Window的类:JYCWindow. 先看看效果:   mygif.gif 关 ...

  7. 最简单webview跳转

    String url = "http://www.qq.com" Uri uri=Uri.parse("http://www.baidu.com"); Inte ...

  8. 浅谈URL跳转与Webview安全

    学习信息安全技术的过程中,用开阔的眼光看待安全问题会得到不同的结论. 在一次测试中我用Burpsuite搜索了关键词url找到了某处url,测试一下发现waf拦截了指向外域的请求,于是开始尝试绕过.第 ...

  9. URL跳转与webview安全浅谈

    URL跳转与webview安全浅谈 我博客的两篇文章拼接在一起所以可能看起来有些乱 起因 在一次测试中我用burpsuite搜索了关键词url找到了某处url我测试了一下发现waf拦截了指向外域的请求 ...

随机推荐

  1. FFmpeg进行屏幕录像和录音

    文章转自:http://www.cucer.cn/2016/03/10/ffmpeg-screen-capture.html 有些时候我们需要对屏幕进行录制,比如制作视频教程,录制直播等.然而这方面的 ...

  2. C#指南,重温基础,展望远方!(9)C#接口

    接口定义了可由类和结构实现的协定. 接口可以包含方法.属性.事件和索引器. 接口不提供所定义的成员的实现代码,仅指定必须由实现接口的类或结构提供的成员. 接口可以采用多重继承. 在以下示例中,接口 I ...

  3. ArcGIS 10 安装程序及破解文件

    1.下载 ArcGIS 10 安装程序及破解文件 后面提供电驴的下载地址(可以使用迅雷.QQ旋风等下载工具下载),下载文件是一个光盘镜像文件:‍ArcGIS_Desktop10_122519.iso. ...

  4. NTP Reply Flood Attack (NTP反射型DDos攻击)

    简介 NTP Reply Flood Attack (NTP射型Ddos攻击)以下简称NTP_Flood是一种利用网络中NTP服务器的脆弱性(无认证,不等价数据交换,UDP协议),来进行DDos行为的 ...

  5. Tomcat 文件夹结构

    文件夹                                                          描写叙述 /bin                               ...

  6. android线程控制UI更新(Handler 、post()、postDelayed()、postAtTime)

    依照以下的理解就是handler与ui线程有一定的关联能够由于更新界面仅仅能在主线程中全部更新界面的地方能够在接受消息的handleMessage那里还有更新界面能够在handler.port(new ...

  7. json对象与json字符串互转方法

    jQuery插件支持的转换方式: 复制代码 代码如下: $.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符串转换成json对象 ...

  8. android.animation(5) - PropertyValuesHolder与Keyframe(转)

    前几篇给大家讲了ValueAnimator.ObjectAnimator的知识,讲解了它们ofInt(),ofFloat(),ofObject()函数的用法.细心的同学可能会注意到,ValueAnim ...

  9. Selenium - 设置元素等待

    一.sleep () 休眠方法   --time 固定等待 在开发自动化框架过程中,最忌讳使用Python自带模块的time的sleep方法进行等待,虽然可以自定义等待时间,但当网络条件良好时, 依旧 ...

  10. Selenium - Webdriver API /ActionChains API

    一.控制浏览器 1.1 控制浏览器窗口大小 # 获取当前浏览器的大小  driver.get_window_size() # 通过像素设置浏览器的大小  driver.set_window_size( ...