iOS UWebView詳解

有時在項目中咱們須要嵌入一些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

  • Excel (.xls)
  • Keynote (.key.zip)
  • Numbers (.numbers.zip)
  • Pages (.pages.zip)
  • PDF (.pdf)
  • Powerpoint (.ppt)

Word (.doc)ios

 

iPhone OS 3.0 supports these additional document types:web

  • Rich Text Format (.rtf)
  • Rich Text Format Directory (.rtfd.zip)
  • Keynote '09 (.key)
  • Numbers '09 (.numbers)

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];
}
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

但記住了,若是你要打開的文件很大,那不可以使用這種方法打開。異步

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
View Code
相關文章
相關標籤/搜索