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來(lái)用webview顯示核畴。load?html string典型的應(yīng)用是:url所對(duì)應(yīng)的web page內(nèi)容太多乘瓤,如果只需要部分的html content,那么可以通過(guò)http request獲取url的html content策泣,然后只選取需要的部分衙傀,然后通過(guò)load html string來(lái)顯示。
自己生成的html萨咕,有時(shí)無(wú)法避免要使用local css, js or image(當(dāng)然你也可以使用url來(lái)鏈接到網(wǎng)上的css/js/image)统抬。
假設(shè)在你的ios app里的resource folder里已經(jīng)存放了a webpage.css and a test.js,那么你生成的html string應(yīng)該這樣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' />則無(wú)法load js(ref link:http://stackoverflow.com/questions/7840127/uiwebview-loadhtmlstring-not-working-in-ios5)
3.當(dāng)你在ios project里創(chuàng)建js或者把js添加進(jìn)來(lái)后危队,by default?.js文件默認(rèn)會(huì)被當(dāng)作代碼被compiled(你在build project時(shí)就會(huì)看到warning)聪建,因此你需要將.js files從“compile sources” move to
"Copy bundle resources",見(jiàn)下圖
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:@"創(chuàng)業(yè)企業(yè)_詳情" 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實(shí)現(xiàn)機(jī)制
Hybrid框架下的app茫陆,使用的Ajax金麸,需要注意的是UIWebViewDelegate不會(huì)監(jiān)測(cè)到Ajax的request,也就是再執(zhí)行Ajax代碼時(shí)簿盅,shouldStartLoadWithReuqest等方法并不會(huì)被調(diào)用钱骂。
其解決方法需要Javascript和navtive code一起來(lái)做,其基本原理可參考這片文章挪鹏,其流程是在Javascript handler中每創(chuàng)建Ajax的請(qǐng)求時(shí),需要將這段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,用于區(qū)別request是否是由Ajax發(fā)出的。
2.1.2在App端獲得js
staticNSString*JSHandler;
+?(void)initialize?{
JSHandler?=?[[NSStringstringWithContentsOfURL:[[NSBundlemainBundle]URLForResource:@"ajax_handler"withExtension:@"js"]encoding:NSUTF8StringEncodingerror:nil]retain];
}
載入頁(yè)面后蔓肯,執(zhí)行這段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相關(guān)知識(shí)
Ajax作為異步Javascript廣泛應(yīng)用在web網(wǎng)站上调限。下面是一個(gè)來(lái)自于w3school的簡(jiǎn)單使用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();
}
點(diǎn)擊button,通過(guò)Ajax的方式獲得書(shū)單踱承。部分內(nèi)容參考于stackoverflow
2.1.4UIWebView載入帶有錨點(diǎn)(anchor)的URL時(shí)存在的問(wèn)題及解決辦法
UIWebView載入帶有錨點(diǎn)(anchor)的URL時(shí)存在的問(wèn)題及解決辦法
http://blog.csdn.net/fengbingyang/article/details/7484453
方案一:
最近在使用ios中的UIWebView顯示本地網(wǎng)頁(yè)時(shí),遇到如下問(wèn)題:
UIWebView加載帶有錨點(diǎn)的URL(如"file:///Users/admin/home.html#pos"),程序使用javascript的range.surroundContents方法在網(wǎng)頁(yè)中為選中文字創(chuàng)建高亮標(biāo)簽桅滋,當(dāng)頁(yè)面高度超過(guò)屏幕高度時(shí),如果頁(yè)面頂部和初始加載時(shí)的位置不同(進(jìn)行過(guò)滾動(dòng)),則每次添加高亮号俐,頁(yè)面就重新跳到初始加載時(shí)的位置,而不是保持當(dāng)前位置。
在PC瀏覽器上嘗試并沒(méi)有出現(xiàn)這種問(wèn)題笨忌,因此猜測(cè)是可能是UIWebView自身的原因。經(jīng)過(guò)一番嘗試,摸索出一種解決辦法维费,具體如下:
在javascript代碼的結(jié)尾部分添加一句location.href="###";
通過(guò)這樣的嘗試,成功讓UIWebView不再跳轉(zhuǎn)到初始加載位置。
PS:如果UIWebView加載的URL不帶錨點(diǎn)恶阴,是不會(huì)出現(xiàn)上述問(wèn)題的。
方案二:在shouldStartLoadWithRequest方法中進(jìn)行url相等判斷缓熟,然后對(duì)于#號(hào)url進(jìn)行延遲執(zhí)行l(wèi)oadNavigationTitle的處理:
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request
navigationType:(UIWebViewNavigationType)navigationType
{
//如果是第一次加載當(dāng)前界面吕世,不需要做判斷
if([selfcheckUrl:request.URLIsEqualToTargetUrl:_currentUrl]) {
_lastRequest= request;
if([urlStrrangeOfString:@"#"].length>0) {
[selfperformSelector:@selector(loadNavigationTitle)withObject:nilafterDelay:0.5];
}
returnYES;
}
//其他處理代碼
}
2.2自定義WebView的userAgent
//獲取iOS默認(rèn)的UserAgent,可以很巧妙地創(chuàng)建一個(gè)空的UIWebView來(lái)獲榷怼:
NSString *userAgent = [[[UIWebView
alloc] init]
stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
//獲取App名稱,我的App有本地化支持迅皇,所以是如下的寫(xiě)法
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}];
// ----------隨便寫(xiě)個(gè)測(cè)試代碼,記得設(shè)置delegate哦茉贡,這只是測(cè)試代碼
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模擬器下得到的結(jié)果是:
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怎么攔截到網(wǎng)頁(yè)里面JS發(fā)起的Ajax請(qǐng)求
http://bbs.csdn.net/topics/390967549?page=1
iOS UIWebView自定義UserAgent