IOS開發系列——UIWebView專題
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
相關文章
- 【iOS開發】從UIWebView到WKWebViewiOSUIWebView
- 【IOS開發基礎系列】Cocoa基礎專題iOS
- iOS開發系列--IOS程式開發概覽iOS
- iOS Cell巢狀UIWebView(內附UIWebView詳解)iOS巢狀UIWebView
- iOS UIWebView、WKWebView注入CookieiOSUIWebViewCookie
- iOS 中UIWebView與WKWebViewiOSUIWebView
- iOS之UIWebView的坑iOSUIWebView
- iOS開發:給UIWebview的導航欄新增返回、關閉按鈕iOSUIWebView
- iOS 開發刷題系列三:NSString 引用計數iOS
- iOS開發 - 動畫實踐系列iOS動畫
- iOS開發系列--UITableView全面解析iOSUIView
- ios uiwebview wkwebview注意點小記iOSUIWebView
- iOS UIWebview仿微信進度條iOSUIWebView
- iOS UIWebView記憶體暴漲問題的解決方法iOSUIWebView記憶體
- iOS開發系列--檢視切換iOS
- IOS開發常用GitHub開源專案iOSGithub
- iOS開發系列--C語言之指標iOSC語言指標
- ArcGIS for iOS 開發系列(1) – 基本概念iOS
- 【問題收集】UIWebView的坑UIWebView
- ios UIWebView 載入網頁、檔案、 htmliOSUIWebView網頁HTML
- 如何為iOS專案開發FrameworkiOSFramework
- iOS開發系列--打造自己的“美圖秀秀”iOS
- iOS開發系列--C語言之預處理iOSC語言
- iOS開發系列—Objective-C之Foundation框架iOSObject框架
- iOS開發系列--C語言之構造型別iOSC語言型別
- iOS開發系列--Objective-C之KVC、KVOiOSObject
- iOS開發系列–打造自己的“美圖秀秀”iOS
- 測試開發專題-開篇
- iOS與JS互動之UIWebView-JavaScriptCore框架iOSJSUIWebViewJavaScript框架
- iOS UIWebView載入時新增進度條01iOSUIWebView
- iOS 開發(五) 專案目錄結構iOS
- iOS開發系列--C語言之基礎知識iOSC語言
- iOS開發系列--C語言之陣列和字串iOSC語言陣列字串
- iOS開發系列--Objective-C之類和物件iOSObject物件
- iOS開發教程之OC語言-歐陽堅-專題視訊課程iOSC語言
- iOS與JS互動之UIWebView協議攔截iOSJSUIWebView協議
- iOS下JS與OC互相呼叫(五)--UIWebView + WebViewJavascriptBridgeiOSJSUIWebViewJavaScript
- 移動開發—iOS日常面試問題移動開發iOS面試