1. 程式人生 > >UIWebView載入本地HTML5檔案

UIWebView載入本地HTML5檔案

一.準備HTML檔案及其資原始檔

使用UIWebView載入本地的HTML檔案 index.html,在index.html中引用了本地的圖片、CSS檔案、JS檔案以及外部的圖片。
index.html內容如下

<html>
    <head>
        <link href="index.css" rel="stylesheet" type="text/css">
        <script type="text/javascript"language="javascript"src="index.js"> 
    </head>
    <body>
        <p>This is local Image</p>
	<img src="Smiley.png" width="50" height="50" />
        <hr/>
        <p>this is local image from CSS.</p>
	<div id="myimage"> </div>
	<hr/>

        <p>this is external image.</p>
	<img src="http://imglf9.ph.126.net/F37NyhuzmvHJChMARbFmHA==/1010495166409149719.jpg" width="300" height="200" />
    </body>
</html>

HTML中會顯示3張圖片,第一張是html從本地讀取的圖片,第二張是通過CSS從本地讀取的圖片,第三張是通過絕對地址從外部讀取的圖片。
index.css檔案內容如下:

body {
    padding: 0px;
    margin: 0px;
}
p {
    font-size: 15px;
    color: #808080;
    font-family: Arial, Helvetica, sans-serif;
}  

#myimage {
    background-image: url(SmallSmiley.png);
    background-repeat: repeat-x;
}
function rewrite()
{
    document.write("This text was written by an external script!")
}

二.載入本地HTML檔案

將html檔案及相關資源新增到專案中

需要注意的是,把js檔案加入到專案時會預設將其當做需要編譯的程式碼,需要在TARGETS->Build Phases中的”Compile Sources”中找到該js檔案,並將其移到上面的Copy Bundle Resources中。

NSString* path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSURL* url = [NSURL fileURLWithPath:path];
NSURLRequest* request = [NSURLRequest requestWithURL:url] ;
[webView loadRequest:request];
NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
NSString *path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSString *html = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[webView loadHTMLString:html baseURL:baseURL];

載入後的顯示效果如下,本地圖片,CSS載入的本地圖片,以及外部圖片都可以正常顯示。

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    [webView stringByEvaluatingJavaScriptFromString:@"rewrite();"];
}

執行js程式碼後,頁面顯示就變成了

三.關於baseURL

loadHTMLString:baseURL:方法的第二個引數是baseURL,baseURL即HTML字串中引用到資源的查詢路徑,沒有引用外部資源時,可以直接傳nil;若引用了外部資源,一般情況下使用mainBundle的路徑即可,即

NSURL *baseURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];

這是因為,Xcode專案中的檔案路徑都是虛擬的,在APP中實際不存在,即在APP中,幾乎所有的檔案都可以從mainBundle根目錄下直接訪問,當然,例外總是存在的。

在將檔案/資料夾加入到專案時,有這樣兩個選項“Create Folder References for any added folders”和“Recursively create groups for any added folders”。

預設情況下為第一種,即所有加入到專案的檔案都會在mainBundle根路徑下,即不管加入專案的檔案的目錄結構如何,在APP中都可以通過mainBundlePath/filename來訪問到;如果採用第二種方式,則就會保留相對路徑,需要通過mainBundlePath/path/filename來訪問。通過這兩種方式到專案的資料夾顯示具有不同的顏色,如下

images1目錄是使用“Create Folder References for any added folders”增加的目錄,images2目錄是使用“Recursively create groups for any added folders”增加的目錄。

獲取images1目錄下檔案的程式碼如下:

NSString* image1Path = [[NSBundle mainBundle] pathForResource:@"image1"ofType:@"jpg"];
NSString* image11Path = [[NSBundle mainBundle] pathForResource:@"image11"ofType:@"jpg"];

images1和images11目錄實際是不存在的,下面程式碼返回的路徑都是nil

NSString* images1Dir = [[NSBundle mainBundle] pathForResource:@"images1"ofType:nil];
NSString* images11Dir = [[NSBundle mainBundle] pathForResource:@"images11"ofType:nil];

對於images2目錄以及目錄下的檔案路徑,其在APP中仍然保持了目錄關係,就不能用上述方法獲取,而且目錄路徑是真實存在的,應該使用的程式碼如下:

NSString* images2Path = [[NSBundle mainBundle] pathForResource:@"image2"ofType:@"jpg"inDirectory:@"images2"];
NSString* image22Path = [[NSBundle mainBundle] pathForResource:@"image22"ofType:@"jpg"inDirectory:@"images2/images22"];
NSString* images2Dir = [[NSBundlemainBundle] pathForResource:@"images2"ofType:nil];
NSString* images2Dir = [[NSBundle mainBundle] pathForResource:@"images22"ofType:nilinDirectory:@"images2"];

還有一種比較特殊的目錄是以.bundle為字尾的目錄,將其加入到專案是不管選擇的是哪個選項,其都會保持其目錄結構。

對子bundle的訪問,可以通過同images2目錄相同的方法訪問,但一般情況下是先獲取到子Bundle,再通過子Bundle獲取到其裡面的資源。

NSBundle *bundle = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:@"images" ofType:@"bundle"]];
NSString* imagebPath = [bundle pathForResource:@"imageb"ofType:@"jpg"];
NSString* imagebbPath = [bundle pathForResource:@"imagebb"ofType:@"jpg" inDirectory:@"imagesb"];
////////

 ios和android都提供了有關webview和javascript通訊的功能,這就使開發者根據手機的系統展示適合手機的介面,是介面開發更加簡單。

我的原型主要實現通過UIWebView展示本地的html、css、javascript檔案,並且和ios互相通訊,用來展示資料。

下面是我實現的一個簡單demo,介面效果如下:

image

點選連線呼叫ios中的提醒功能:

image

實現過程:

  • 首先建立一個工程,ipad.web1,編譯執行成功。
  • 實現webview的程式碼:
 

#import <UIKit/UIKit.h> 

@interface ipad_web1ViewController : UIViewController  <UIWebViewDelegate>{      IBOutlet UIWebView *myWebView;  }  @property (nonatomic,retain) UIWebView *myWebView;  @end

相應的.m檔案:

#import "ipad_web1ViewController.h" 

@implementation ipad_web1ViewController  @synthesize myWebView;  - (void)viewDidLoad {      [super viewDidLoad];      self.myWebView.delegate=self;      NSString *path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];      [myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath: path]]];  }  - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {      return YES;  } 

- (void)didReceiveMemoryWarning {      [super didReceiveMemoryWarning];  } 

- (void)viewDidUnload {      self.myWebView=nil;  } 

- (void)dealloc {      [self.myWebView release];      [super dealloc];  }  #pragma mark –  #pragma mark UIWebViewDelegate  - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {      if ( [request.mainDocumentURL.relativePath isEqualToString:@"/click/false"] ) {             NSLog( @"not clicked" );          return false;      }      if ( [request.mainDocumentURL.relativePath isEqualToString:@"/click/true"] ) {        //the image is clicked, variable click is true          NSLog( @"image clicked" );          UIAlertView* alert=[[UIAlertView alloc]initWithTitle:@"JavaScript called"                                                       message:@"You’ve called iPhone provided control from javascript!!" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil];          [alert show];          [alert release];          return false;      }      return true;  }  - (void)webViewDidStartLoad:(UIWebView *)webView  {      NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];      NSLog(@"title11=%@",title);  }  - (void)webViewDidFinishLoad:(UIWebView *)webView  {      NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];      NSLog(@"title=%@",title);      //新增資料     [myWebView stringByEvaluatingJavaScriptFromString:@"var field = document.getElementById('field_2');"        "field.value='Multiple statements - OK';"];      //[myWebView stringByEvaluatingJavaScriptFromString:@"var script = document.createElement('script');"   //     "script.type = 'text/javascript';"   //     "script.text = \"function myFunction() { "   //     "var field = document.getElementById('field_3');"   //     "field.value='Calling function - OK';"   //     "}\";"   //     "document.getElementsByTagName('head')[0].appendChild(script);"];   //     //    [myWebView stringByEvaluatingJavaScriptFromString:@"myFunction();"];   }  - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error  {  }  @end

  • 最後在Interface Builder中新增UIwebView控制元件,並且和相應的實體相關聯。

   NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];      NSLog(@"title=%@",title);

主要是獲取html檔案的title名字。

[myWebView stringByEvaluatingJavaScriptFromString:@"var field = document.getElementById('field_2');"        "field.value='Multiple statements - OK';"];

新增相應的表單資訊。

  • 接下來新增index.html檔案:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  <html xmlns="http://www.w3.org/1999/xhtml">  <head>      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />      <title>How to build an iPhone website</title>      <meta name="author" content="will" />      <meta name="copyright" content="copyright 2008 www.engageinteractive.co.uk" />      <meta name="description" content="Welcome to engege interactive on the iPhone!" />      <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;">      <link rel="apple-touch-icon" href="images/template/engage.png"/>      <style type="text/css">          @import url("layout.css");      </style>      <script type="text/javascript" src="test.js"></script>     </head>  <body>  <h1>測試</h1>     <center><a href="javascript:void(0)" onMouseDown="imageClicked()">click me</a></center>     <form>         <input id="field_1" type="text" name="value" /><br/><br/><br/>         <input id="field_2" type="text" name="value" /><br/><br/><br/>         <input id="field_3" type="text" name="value" /><br/><br/><br/>       </form>   </body>  </html>

  • 新增相應的css檔案:

body {      background-color: #F2F5A9;  }

  • 新增相應的js檔案:

function imageClicked(){      var clicked=true;      window.location="/click/"+clicked;  }

執行,點選連線應該不出相應的對話方塊,說明相應的javascript沒有生效。修改辦法是開啟targets,點選ipad.web1,移動相應的test.js檔案到下圖即可。