有時在項目中咱們須要嵌入一些web相關的內容,這時你就要用到一個叫UIWebView的東西(UIWebView還能夠打開一些文件等,如pdf等),在android和iOS中都有這個東西,使用起來也很方便javascript
只要發送一個request加載web content就行,並且它也支持會退和前進,此外,你還能夠經過它與網頁中的js進行交互,下面看詳細講解。html
1、先來看看UIWebView的打開文件的功能,具體支持的文件類型以下:java
iPhone OS 2.2.1 supports the following document types:android
Word (.doc)ios
iPhone OS 3.0 supports these additional document types:web
Pages '09 (.pages)瀏覽器
看到了吧,經常使用的word,execl 、PDF都能打開。加載這些本地數據時,你可使用loadRequest,或者 loadData:MIMEType:textEncodingName:baseURL:,代碼以下:
app
-(void)loadDocument:(NSString*)documentName inView:(UIWebView*)webView { //這是你要打開的文件的存放路徑,也能夠是document目錄下的路徑 NSString *path = [[NSBundle mainBundle] pathForResource:documentName ofType:nil]; //當路徑在本地時,就用下面的方法換成url,若是在遠程web上,則用 //urlWithString NSURL *url = [NSURL fileURLWithPath:path]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [webView loadRequest:request]; }
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]; }
但記住了,若是你要打開的文件很大,那不可以使用這種方法打開。異步
2、當你要加載一些html數據時你可使用 loadHTMLString:baseURL: 你也能夠用上面的方法加載,對於該控件,最大的做用莫非加載網頁了,下面詳細介紹。。。ide
1.你可使用它的方法 loadRequest:加載web content, 中止加載則使用stopLoading,固然,你確定要知道它是否正在加載,此時你能夠經過屬性loading進行判斷。
2.若是你容許用戶向前、向後瀏覽網頁歷史紀錄時,你可使用方法goBack 和 goForward,固然在使用上面的方法前,你能夠判斷是否能繼續向前,或向後,canGoBack、canGoForward.
3.UIWebView還具備內容檢測功能,當網頁內容中出現了一些手機號碼、網頁連接等東西時,它可以動態識別,若是你點擊了它可以識別的東西,則它會進行相應的處理,如:當發現你點擊的是電話號碼時,則直接撥號,當發現你點擊的是網址,則打開瀏覽器前往連接,但UIWebView默認只會識別電話號碼,不過你能夠經過設置它的 來dataDetectorTypes屬性來設置到底支持那種類型的識別,該屬性值能夠是下面的這些
UIDataDetectorTypePhoneNumber = 1 << 0, //識別電話號碼 UIDataDetectorTypeLink = 1 << 1, //識別網址,連接等 UIDataDetectorTypeAddress = 1 << 2, // 識別地址 UIDataDetectorTypeCalendarEvent = 1 << 3, // 識別時間 UIDataDetectorTypeNone = 0, //全都不識別 UIDataDetectorTypeAll = NSUIntegerMax // 所有識別
你能夠用 或"|" 指定識別其中的幾種
4.UIWebView具備和UIScrollView同樣的放大、縮小功能,你只要設置屬性scalesPageToFit,爲YES就能夠達到效果,正由於如此,因此你的UIWebView 不能嵌入到UIScrollView中去,通常加載網頁的代碼以下:
[self.myWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.apple.com/"]]];
注意了:loadRequest的方法自己就是異步的,因此你沒必要怕影響性能,本身給他再搞個異步。
5.UIWebView 還有個delegate,主要是用來檢測網頁的加載,以及與網頁中的js實現交互等,與js交互的功能很叼吧,但實現起來但是很是簡單,主要是經過它的方法
- (NSString *)stringByEvaluatingJavaScriptFromString:()NSString *script
實現的,你傳入的參數,也就是script的js代碼不能超過10M 大。
6.下面是一些代碼,隨便寫的,不是很完善。裏面也有註釋
#import "ViewController.h" @interface ViewController (){ UIWebView *webView; UIButton *backBtn; UIButton *forwardBtn; UIButton *refreshBtn; NSURLRequest *currentRequest; //加載時是否發生error BOOL hasError; } @end @implementation ViewController - (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; //經過監聽web view是否可以向前 或 向後來決定按鈕是否可用,就像AVCaptureDevice那樣,能監聽它本身的屬性---adjustFocusing的變化,這樣就知道它是否在進行聚焦,後面發現,它壓根就不允這樣,試想下,若是知道UIWebView可否前進,或後退,而後根據這個來設置前進和後退的按鈕是否可用,那多帥啊(固然,咱們能夠用定時器實現這功能,但總感受很差),但願之後能這樣。。。 [webView addObserver:self forKeyPath:@"canGoBack" options:NSKeyValueObservingOptionNew context:nil]; [webView addObserver:self forKeyPath:@"canGoForward" options:NSKeyValueObservingOptionNew context:nil]; } //在這迷糊了,發現一直監聽不到,不像 AVCaptureDevice那樣,能監聽它本身的屬性---adjustFocusing -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(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]; //經過監聽web view是否可以向前 或 向後來決定按鈕是否可用,之前作自定義相機的時候能用這種方式監聽是否在自動對焦,而後做出相應的處理, //但如今無論怎麼試都沒用,報錯顯示不能這樣作,也不知爲何。。。 [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. } #pragma makr -- 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]; } //發生錯誤時則從新加載主頁 if (hasError) { [webView loadRequest:currentRequest]; }else{ [webView reload]; } } -(void)goForward:(id)sender{ NSLog(@"in goForward"); if (webView.loading) { [webView stopLoading]; } [webView goForward]; } #pragma mark -- UIWebDelegate - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{ return YES; } // 當UIWevView開始加載內容時調用 - (void)webViewDidStartLoad:(UIWebView *)webView{ NSLog(@"in webViewDidStartLoad"); [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; } // 當UIWevView完成內容加載時調用 - (void)webViewDidFinishLoad:(UIWebView *)webView{ NSLog(@"in webViewDidFinishLoad"); [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; //下面是測試 web view和js交互的例子 //該方法是把你傳進來的 js 代碼傳入web網頁中,而後返回執行的結果,返回null則爲執行失敗 NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"]; NSLog(@"title = %@",title); //下面是網上大牛寫的,嵌入一個值的,是要針對指定網頁的 [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:@"<html><center><font size=+5 color='red'>An error occurred:<br>%@</font></center></html>",[error localizedDescription]] baseURL:nil]; hasError = YES; } @end