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