UIWebView专题
1初始化
1.1API接口使用
1.1.1loadhtmlstring
iOS: UIWebview loadhtmlstring & Localcss/js/image resources
http://blog.csdn.net/totogogo/article/details/7613790
UIWebView既可以load by url,还可以load html string。即你可以自己generate html string来用webview显示。load html string典型的应用是:url所对应的web page内容太多,如果只需要部分的html content,那么可以通过http request获取url的html content,然后只选取需要的部分,然后通过load html string来显示。
自己生成的html,有时无法避免要使用local css, js or image(当然你也可以使用url来链接到网上的css/js/image)。
假设在你的ios app里的resource folder里已经存放了a webpage.css and a test.js,那么你生成的html string应该这样include them
NSString*
htmlHeader=@"
type='text/css'>@import url('webpage.css');
type='text/javascript' charset='utf-8' src='test.js'>";
NSString* htmlBody=@"";
NSString*htmlFooter=@"";
NSString*strHtml=[[NSStringalloc]initWithFormat:@"%@%@%@",htmlHeader,htmlBody,htmlFooter];
[webViewloadHTMLString:strHtmlbaseURL:[NSURLfileURLWithPath: [[NSBundlemainBundle]resourcePath]isDirectory:YES]];
注意:
1.baseURL就是你的resourcefolder path
2.如果把charset='utf-8' src='test.js'>改成
charset='utf-8' src='test.js' />则无法load js(ref link:http://stackoverflow.com/questions/7840127/uiwebview-loadhtmlstring-not-working-in-ios5)
3.当你在ios project里创建js或者把js添加进来后,by default .js文件默认会被当作代码被compiled(你在build project时就会看到warning),因此你需要将.js files从“compile sources” move to
"Copy bundle resources",见下图
1.1.2UIWebView加载本地html文件
UIWebView *webView_=[[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 320,400)];
webView_.delegate=self;
[self.view addSubview:webView_];
NSString *filePath = [[NSBundle
mainBundle]pathForResource:@"创业企业_详情" ofType:@"html"];
NSString *htmlString = [NSStringstringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
[webView_ loadHTMLString:htmlString baseURL:[NSURL
URLWithString:filePath]];
2与web交互
2.1WebView中使用Ajax
2.1.1实现机制
Hybrid框架下的app,使用的Ajax,需要注意的是UIWebViewDelegate不会监测到Ajax的request,也就是再执行Ajax代码时,shouldStartLoadWithReuqest等方法并不会被调用。
其解决方法需要Javascript和navtive code一起来做,其基本原理可参考这片文章,其流程是在Javascript handler中每创建Ajax的请求时,需要将这段js存在ajax_handler.js放在app中
vars_ajaxListener=newObject();
s_ajaxListener.tempOpen=XMLHttpRequest.prototype.open;
s_ajaxListener.tempSend=XMLHttpRequest.prototype.send;
s_ajaxListener.callback=function() {
window.location='mpAjaxHandler://'+ this.url;
};
XMLHttpRequest.prototype.open=function(a,b) {
if (!a) vara='';
if (!b) varb='';
s_ajaxListener.tempOpen.apply(this, arguments);
s_ajaxListener.method=a;
s_ajaxListener.url=b;
if (a.toLowerCase() == 'get') {
s_ajaxListener.data=b.split('?');
s_ajaxListener.data=s_ajaxListener.data[1];
}
}
XMLHttpRequest.prototype.send=function(a,b) {
if (!a) vara='';
if (!b) varb='';
s_ajaxListener.tempSend.apply(this, arguments);
if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data=a;
s_ajaxListener.callback();
}
其中的"mpAjaxHandler"为自定义的Scheme,用于区别request是否是由Ajax发出的。
2.1.2在App端获得js
staticNSString*JSHandler;
+ (void)initialize {
JSHandler = [[NSStringstringWithContentsOfURL:[[NSBundlemainBundle]URLForResource:@"ajax_handler"withExtension:@"js"]encoding:NSUTF8StringEncodingerror:nil]retain];
}
载入页面后,执行这段js
- (void)webViewDidStartLoad:(UIWebView*)webView {
[webViewstringByEvaluatingJavaScriptFromString:JSHandler];
}
拦截住Request,不让webview的URL做出改变
#define CocoaJSHandler @"mpAjaxHandler"
- (BOOL)webView:(UIWebView*)webViewshouldStartLoadWithRequest:(NSURLRequest*)requestnavigationType:(UIWebViewNavigationType)navigationType {
if([[[requestURL]scheme]isEqual:CocoaJSHandler]) {
NSString*requestedURLString = [[[requestURL]absoluteString]substringFromIndex:[CocoaJSHandlerlength] +3];
NSLog(@"ajax request: %@", requestedURLString);
returnNO;
}
returnYES;
}
2.1.3Ajax相关知识
Ajax作为异步Javascript广泛应用在web网站上。下面是一个来自于w3school的简单使用Ajax的例子:
function loadXMLDoc()
{
var xmlhttp;
var txt,x,i;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=newXMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=newActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 &&xmlhttp.status==200)
{
xmlDoc=xmlhttp.responseXML;
txt="";
x=xmlDoc.getElementsByTagName("title");
for (i=0;i;i++)
{
txt=txt+ x[i].childNodes[0].nodeValue + "/>";
}
document.getElementById("myDiv").innerHTML=txt;
}
}
xmlhttp.open("GET","http://www.w3school.com.cn/example/xmle/books.xml",true);
xmlhttp.send();
}
点击button,通过Ajax的方式获得书单。部分内容参考于stackoverflow
2.1.4UIWebView载入带有锚点(anchor)的URL时存在的问题及解决办法
UIWebView载入带有锚点(anchor)的URL时存在的问题及解决办法
http://blog.csdn.net/fengbingyang/article/details/7484453
方案一:
最近在使用ios中的UIWebView显示本地网页时,遇到如下问题:
UIWebView加载带有锚点的URL(如"file:///Users/admin/home.html#pos"),程序使用javascript的range.surroundContents方法在网页中为选中文字创建高亮标签,当页面高度超过屏幕高度时,如果页面顶部和初始加载时的位置不同(进行过滚动),则每次添加高亮,页面就重新跳到初始加载时的位置,而不是保持当前位置。
在PC浏览器上尝试并没有出现这种问题,因此猜测是可能是UIWebView自身的原因。经过一番尝试,摸索出一种解决办法,具体如下:
在javascript代码的结尾部分添加一句location.href="###";
通过这样的尝试,成功让UIWebView不再跳转到初始加载位置。
PS:如果UIWebView加载的URL不带锚点,是不会出现上述问题的。
方案二:在shouldStartLoadWithRequest方法中进行url相等判断,然后对于#号url进行延迟执行loadNavigationTitle的处理:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request
navigationType:(UIWebViewNavigationType)navigationType
{
//如果是第一次加载当前界面,不需要做判断
if([selfcheckUrl:request.URLIsEqualToTargetUrl:_currentUrl]) {
_lastRequest= request;
if([urlStrrangeOfString:@"#"].length>0) {
[selfperformSelector:@selector(loadNavigationTitle)withObject:nilafterDelay:0.5];
}
returnYES;
}
//其他处理代码
}
2.2自定义WebView的userAgent
//获取iOS默认的UserAgent,可以很巧妙地创建一个空的UIWebView来获取:
NSString *userAgent = [[[UIWebView
alloc] init]
stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
//获取App名称,我的App有本地化支持,所以是如下的写法
NSString *appName =
NSLocalizedStringFromTable(@"CFBundleDisplayName",
@"InfoPlist", nil);
//如果不需要本地化的App名称,可以使用下面这句
//NSString *appName= [[NSBundle mainBundle]infoDictionary][@"CFBundleDisplayName"];
NSString*version = [[NSBundlemainBundle]infoDictionary][@"CFBundleShortVersionString"];
NSString *customUserAgent = [userAgent
stringByAppendingFormat:@" %@/%@",appName, version];
[[NSUserDefaults standardUserDefaults]
registerDefaults:@{@"UserAgent":customUserAgent}];
// ----------随便写个测试代码,记得设置delegate哦,这只是测试代码
UIWebView *webView = [[UIWebView
alloc] init];
webView.delegate = self;
[webView loadRequest:[NSURLRequest
requestWithURL:[NSURL URLWithString:@"http://www.baidu.com/"]]];
-
(void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(@"UserAgent = %@",
[webView
stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"]);
}
Xcode 5.1.1iOS 7.1模拟器下得到的结果是:
Mozilla/5.0 (iPhone; CPU iPhone OS 7_1 like Mac OS X)
AppleWebKit/537.51.2 (KHTML, like Gecko)中华浏览器/1.2.2
3参考链接
Hybrid--WebView中使用Ajax
http://blog.csdn.net/xunyn/article/details/38389247
UIWebView怎么拦截到网页里面JS发起的Ajax请求
http://bbs.csdn.net/topics/390967549?page=1
iOS UIWebView自定义UserAgent
http://blog.sina.com.cn/s/blog_6db188450102v529.html