iOS UWebView详解

iOS UWebView详解 - ctaodrea

时间 2013-09-06 17:52:00博客园精华区

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

主题JavaScriptiOS开发

有时在项目中我们需要嵌入一些web相关的内容,这时你就要用到一个叫UIWebView的东西(UIWebView还可以打开一些文件等,如pdf等),在android和iOS中都有这个东西,使用起来也很方便

只要发送一个request加载web content就行,而且它也支持会退和前进,此外,你还可以通过它与网页中的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都能打开。加载这些本地数据时,你可以使用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数据时你可以使用loadHTMLString:baseURL:你也可以用上面的方法加载,对于该控件,最大的作用莫非加载网页了,下面详细介绍。。。

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"@interfaceViewController (){

UIWebView*webView;

UIButton*backBtn;

UIButton*forwardBtn;

UIButton*refreshBtn;

NSURLRequest*currentRequest;//加载时是否发生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;//通过监听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)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];//通过监听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.}#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];

}//发生错误时则重新加载主页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开始加载内容时调用- (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:@"An error occurred:
%@",[error localizedDescription]] baseURL:nil];

hasError=YES;

}@end

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容

  • iOS开发系列--网络开发 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博、微信等,这些应用本身可...
    lichengjin阅读 3,629评论 2 7
  • http://www.cnblogs.com/mddblog/p/5281748.html 一、整体介绍 UIWe...
    F麦子阅读 1,206评论 0 2
  • 一、WebView WebView就是一个内嵌浏览器控件,在iOS中主要有两种WebView:UIWebView和...
    iOS祎阅读 1,068评论 0 2
  • 前言 关于UIWebView的介绍,相信看过上文的小伙伴们,已经大概清楚了吧,如果有问题,欢迎提问。 本文是本系列...
    CoderLF阅读 8,939评论 2 12
  • OS之UIWebView的使用 刚接触IOS开发1年多,现在对于 混合式 移动端开发越来越流行,因为开发成本上、速...
    知之未道阅读 1,652评论 0 4