iOS UWebView詳解

iOS UWebView詳解 - ctaodrea

時間?2013-09-06 17:52:00博客園精華區(qū)

原文http://www.cnblogs.com/ctaodream/p/3305931.html

主題JavaScriptiOS開發(fā)

有時在項目中我們需要嵌入一些web相關(guān)的內(nèi)容,這時你就要用到一個叫UIWebView的東西(UIWebView還可以打開一些文件等,如pdf等),在android和iOS中都有這個東西,使用起來也很方便

只要發(fā)送一個request加載web content就行,而且它也支持會退和前進,此外,你還可以通過它與網(wǎng)頁中的js進行交互,下面看詳細講解。

一、先來看看UIWebView的打開文件的功能,具體支持的文件類型如下:

iPhone OS 2.2.1 supports the following document types:

Excel (.xls)

Keynote (.key.zip)

Numbers (.numbers.zip)

Pages (.pages.zip)

PDF (.pdf)

Powerpoint (.ppt)

Word (.doc)

iPhone OS 3.0 supports these additional document types:

Rich Text Format (.rtf)

Rich Text Format Directory (.rtfd.zip)

Keynote '09 (.key)

Numbers '09 (.numbers)

Pages '09 (.pages)

看到了吧,常用的word,execl 、PDF都能打開。加載這些本地數(shù)據(jù)時,你可以使用loadRequest,或者loadData:MIMEType:textEncodingName:baseURL:,代碼如下:

-(void)loadDocument:(NSString*)documentName inView:(UIWebView*)webView

{//這是你要打開的文件的存放路徑,也可以是document目錄下的路徑NSString *path =[[NSBundle mainBundle] pathForResource:documentName ofType:nil];//當路徑在本地時,就用下面的方法換成url,如果在遠程web上,則用//urlWithStringNSURL *url =[NSURL fileURLWithPath:path];

NSURLRequest*request =[NSURLRequest requestWithURL:url];

[webView loadRequest:request];

}

View Code

NSString*thePath= [[NSBundle mainBundle] pathForResource:@"iPhone_User_Guide"ofType:@"pdf"];if(thePath) {

NSData*pdfData=[NSData dataWithContentsOfFile:thePath];

[(UIWebView*)self.view loadData:pdfData MIMEType:@"application/pdf"textEncodingName:@"utf-8"baseURL:nil];

}

View Code

但記住了,如果你要打開的文件很大,那不可使用這種方法打開。

二、當你要加載一些html數(shù)據(jù)時你可以使用loadHTMLString:baseURL:你也可以用上面的方法加載,對于該控件,最大的作用莫非加載網(wǎng)頁了,下面詳細介紹。。。

1.你可以使用它的方法 loadRequest:加載web content, 停止加載則使用stopLoading,當然,你肯定要知道它是否正在加載,此時你可以通過屬性loading進行判斷。

2.如果你允許用戶向前、向后瀏覽網(wǎng)頁歷史紀錄時,你可以使用方法goBack 和 goForward,當然在使用上面的方法前,你可以判斷是否能繼續(xù)向前,或向后,canGoBack、canGoForward.

3.UIWebView還具有內(nèi)容檢測功能,當網(wǎng)頁內(nèi)容中出現(xiàn)了一些手機號碼、網(wǎng)頁鏈接等東西時,它能夠動態(tài)識別,如果你點擊了它能夠識別的東西,則它會進行相應的處理,如:當發(fā)現(xiàn)你點擊的是電話號碼時,則直接撥號,當發(fā)現(xiàn)你點擊的是網(wǎng)址,則打開瀏覽器前往鏈接,但UIWebView默認只會識別電話號碼,不過你可以通過設(shè)置它的 ? ?來dataDetectorTypes屬性來設(shè)置到底支持那種類型的識別,該屬性值可以是下面的這些

UIDataDetectorTypePhoneNumber? =1<<0,? //識別電話號碼UIDataDetectorTypeLink=1<<1, //識別網(wǎng)址,鏈接等UIDataDetectorTypeAddress=1<<2, // 識別地址UIDataDetectorTypeCalendarEvent=1<<3, // 識別時間UIDataDetectorTypeNone=0, //全都不識別UIDataDetectorTypeAll=NSUIntegerMax// 全部識別

你可以用 或"|" 指定識別其中的幾種

4.UIWebView具有和UIScrollView一樣的放大、縮小功能,你只要設(shè)置屬性scalesPageToFit,為YES就可以達到效果,正因為如此,所以你的UIWebView 不能嵌入到UIScrollView中去,一般加載網(wǎng)頁的代碼如下:

[self.myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]]];注意了:loadRequest的方法本身就是異步的,所以你不必怕影響性能,自己給他再搞個異步。

5.UIWebView 還有個delegate,主要是用來檢測網(wǎng)頁的加載,以及與網(wǎng)頁中的js實現(xiàn)交互等,與js交互的功能很叼吧,但實現(xiàn)起來可是非常簡單,主要是通過它的方法

-?(NSString*)stringByEvaluatingJavaScriptFromString:(NSString*)script

實現(xiàn)的,你傳入的參數(shù),也就是script的js代碼不能超過10M 大。

6.下面是一些代碼,隨便寫的,不是很完善。里面也有注釋

#import"ViewController.h"@interfaceViewController (){

UIWebView*webView;

UIButton*backBtn;

UIButton*forwardBtn;

UIButton*refreshBtn;

NSURLRequest*currentRequest;//加載時是否發(fā)生errorBOOL hasError;

}@end@implementationViewController- (void)viewDidLoad

{

[super viewDidLoad];//Do any additional setup after loading the view, typically from a nib.webView? = [[UIWebView alloc]initWithFrame:CGRectMake(0,0,320,400)];

[self.view addSubview:webView];

webView.scalesPageToFit=YES;

webView.allowsInlineMediaPlayback=YES;

backBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];

[backBtn setFrame:CGRectMake(10,420,80,30)];

[backBtn setTitle:@"back"forState:UIControlStateNormal];

[backBtn addTarget:self action:@selector(goBack:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:backBtn];

refreshBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];

[refreshBtn setFrame:CGRectMake(120,420,80,30)];

[refreshBtn setTitle:@"refresh"forState:UIControlStateNormal];

[refreshBtn addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:refreshBtn];

forwardBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];

[forwardBtn setFrame:CGRectMake(230,420,80,30)];

[forwardBtn setTitle:@"forward"forState:UIControlStateNormal];

[forwardBtn addTarget:self action:@selector(goForward:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:forwardBtn];//請求鏈接currentRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];

hasError=NO;//通過監(jiān)聽web view是否能夠向前 或 向后來決定按鈕是否可用,就像AVCaptureDevice那樣,能監(jiān)聽它自己的屬性---adjustFocusing的變化,這樣就知道它是否在進行聚焦,后面發(fā)現(xiàn),它壓根就不允這樣,試想下,如果知道UIWebView能否前進,或后退,然后根據(jù)這個來設(shè)置前進和后退的按鈕是否可用,那多帥啊(當然,我們可以用定時器實現(xiàn)這功能,但總感覺不好),希望以后能這樣。。。[webView addObserver:self forKeyPath:@"canGoBack"options:NSKeyValueObservingOptionNew context:nil];

[webView addObserver:self forKeyPath:@"canGoForward"options:NSKeyValueObservingOptionNew context:nil];

}//在這迷糊了,發(fā)現(xiàn)一直監(jiān)聽不到,不像 AVCaptureDevice那樣,能監(jiān)聽它自己的屬性---adjustFocusing-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)objectchange:(NSDictionary *)change context:(void*)contex{

NSLog(@"in observeValueForKeyPath");if([keyPath isEqualToString:@"canGoBack"]) {

BOOL canGoBack= [[change objectForKey:NSKeyValueChangeNewKey] isEqualToNumber:[NSNumber numberWithInt:1]];if(canGoBack) {

[backBtn setEnabled:YES];

}else{

[backBtn setEnabled:NO];

}

}else{

BOOL canGoForward= [[change objectForKey:NSKeyValueChangeNewKey] isEqualToNumber:[NSNumber numberWithInt:1]];if(canGoForward) {

[forwardBtn setEnabled:YES];

}else{

[forwardBtn setEnabled:NO];

}

}

}-(void)viewDidAppear:(BOOL)animated{

[super viewDidAppear:animated];//通過監(jiān)聽web view是否能夠向前 或 向后來決定按鈕是否可用,以前做自定義相機的時候能用這種方式監(jiān)聽是否在自動對焦,然后作出相應的處理,//但現(xiàn)在不管怎么試都沒用,報錯顯示不能這樣做,也不知為什么。。。[webView addObserver:self forKeyPath:@"canGoBack"options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

[webView addObserver:self forKeyPath:@"canGoForward"options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];

webView.delegate=self;

[webView loadRequest:currentRequest];

}-(void)viewWillDisappear:(BOOL)animated{

[super viewWillDisappear:animated];if(webView.loading) {

[webView stopLoading];

}

webView.delegate=nil;

}- (void)didReceiveMemoryWarning

{

[super didReceiveMemoryWarning];//Dispose of any resources that can be recreated.}#pragmamakr -- button event action-(void)goBack:(id)sender{

NSLog(@"in goBack");if(webView.loading) {

[webView stopLoading];

}

[webView goBack];

}-(void)refresh:(id)sender{

NSLog(@"in refresh");if(webView.loading) {

[webView stopLoading];

}//發(fā)生錯誤時則重新加載主頁if(hasError) {

[webView loadRequest:currentRequest];

}else{

[webView reload];

}

}-(void)goForward:(id)sender{

NSLog(@"in goForward");if(webView.loading) {

[webView stopLoading];

}

[webView goForward];

}#pragmamark -- UIWebDelegate- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{returnYES;

}//當UIWevView開始加載內(nèi)容時調(diào)用- (void)webViewDidStartLoad:(UIWebView *)webView{

NSLog(@"in webViewDidStartLoad");

[UIApplication sharedApplication].networkActivityIndicatorVisible=YES;

}//當UIWevView完成內(nèi)容加載時調(diào)用- (void)webViewDidFinishLoad:(UIWebView *)webView{

NSLog(@"in webViewDidFinishLoad");

[UIApplication sharedApplication].networkActivityIndicatorVisible=NO;//下面是測試 web view和js交互的例子//該方法是把你傳進來的 js 代碼傳入web網(wǎng)頁中,然后返回執(zhí)行的結(jié)果,返回null則為執(zhí)行失敗NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];

NSLog(@"title = %@",title);//下面是網(wǎng)上大牛寫的,嵌入一個值的,是要針對指定網(wǎng)頁的[webView stringByEvaluatingJavaScriptFromString:@"var script = document.createElement('script');""script.type = 'text/javascript';""script.text = \"function myFunction() {""var field = document.getElementsByName('q')[0];""field.value='朱祁林';""document.forms[0].submit();""}\";""document.getElementsByTagName('head')[0].appendChild(script);"];

[webView stringByEvaluatingJavaScriptFromString:@"myFunction();"];

}- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{

NSLog(@"in didFailLoadWithError");

[UIApplication sharedApplication].networkActivityIndicatorVisible=NO;

[webView loadHTMLString:[NSString stringWithFormat:@"An error occurred:
%@",[error localizedDescription]] baseURL:nil];

hasError=YES;

}@end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • iOS開發(fā)系列--網(wǎng)絡開發(fā) 概覽 大部分應用程序都或多或少會牽扯到網(wǎng)絡開發(fā),例如說新浪微博、微信等,這些應用本身可...
    lichengjin閱讀 3,726評論 2 7
  • http://www.cnblogs.com/mddblog/p/5281748.html 一、整體介紹 UIWe...
    F麥子閱讀 1,267評論 0 2
  • 一、WebView WebView就是一個內(nèi)嵌瀏覽器控件,在iOS中主要有兩種WebView:UIWebView和...
    iOS祎閱讀 1,119評論 0 2
  • 前言 關(guān)于UIWebView的介紹,相信看過上文的小伙伴們,已經(jīng)大概清楚了吧,如果有問題,歡迎提問。 本文是本系列...
    CoderLF閱讀 9,024評論 2 12
  • OS之UIWebView的使用 剛接觸IOS開發(fā)1年多,現(xiàn)在對于 混合式 移動端開發(fā)越來越流行,因為開發(fā)成本上、速...
    知之未道閱讀 1,670評論 0 4