iOS UWebView详解
有时在项目中我们需要嵌入一些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上,则用
//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];
}
但记住了,如果你要打开的文件很大,那不可使用这种方法打开。
二、当你要加载一些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"
@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(, , , )];
[self.view addSubview:webView];
webView.scalesPageToFit = YES;
webView.allowsInlineMediaPlayback = YES;
backBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[backBtn setFrame:CGRectMake(, , , )];
[backBtn setTitle:@"back" forState:UIControlStateNormal];
[backBtn addTarget:self action:@selector(goBack:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:backBtn];
refreshBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[refreshBtn setFrame:CGRectMake(, , , )];
[refreshBtn setTitle:@"refresh" forState:UIControlStateNormal];
[refreshBtn addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:refreshBtn];
forwardBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[forwardBtn setFrame:CGRectMake(, , , )];
[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:]];
if (canGoBack) {
[backBtn setEnabled:YES];
}else{
[backBtn setEnabled:NO];
}
}else{
BOOL canGoForward = [[change objectForKey:NSKeyValueChangeNewKey] isEqualToNumber:[NSNumber numberWithInt:]];
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
iOS UWebView详解的更多相关文章
- 【转】IOS AutoLayout详解(三)用代码实现(附Demo下载)
转载自:blog.csdn.net/hello_hwc IOS SDK详解 前言: 在开发的过程中,有时候创建View没办法通过Storyboard来进行,又需要AutoLayout,这时候用代码创建 ...
- IOS SDK详解
来源:http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html?page=1#42803301 博客专栏>移动开发专栏>I ...
- iOS路由详解
本文如题,路由详解,注定是一篇详细解释iOS路由原理及使用的文章,由于此时正在外地出差,无法详细一一写出,只能不定时的补充. 一.什么是iOS路由 路由一词来源于路由器,可以实现层级之间消息转发的功能 ...
- IOS 手势详解
在IOS中手势可以让用户有很好的体验,因此我们有必要去了解一下手势. (在设置手势是有很多值得注意的地方) *是需要设置为Yes的点击无法响应* *要把手势添加到所需点击的View,否则无法响应* 手 ...
- IOS SizeClasses 详解
SizeClasses 详解 iOS 8在应用界面的可视化设计上添加了一个新的特性-Size Classes.对于任何设备来说,界面的宽度和高度都只分为三种描述:紧凑,任意和宽松.这样开发者便可以无视 ...
- iOS模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.
Write in the first[写在最前] 对于从事 iOS 开发人员来说,当提到 ** runtime时,我想都可以说出来 「runtime 运行时」和基本使用的方法.相信很多开发者跟我当初一 ...
- iOS 模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.
引导 Copyright © PBwaterln Unauthorized shall not be *copy reprinted* . 对于从事 iOS 开发人员来说,所有的人都会答出「runti ...
- ios学习--详解IPhone动画效果类型及实现方法
详解IPhone动画效果类型及实现方法是本文要介绍的内容,主要介绍了iphone中动画的实现方法,不多说,我们一起来看内容. 实现iphone漂亮的动画效果主要有两种方法,一种是UIView层面的,一 ...
- iOS CoreAnimation详解(一) 有关Layer的动画
以前由于项目需要 也写了一些动画 ,但是知识不系统,很散.这段时间趁着项目完成的空袭,来跟着大神的脚步系统的总结一下iOS中Core Animation的知识点. 原博客地址:http://blog. ...
随机推荐
- Swift # 项目框架
利用Swift--简单的项目界面流程. TabBar+Navigation底部导航控制,界面的切换. GitHub源码分享,地址: URL:https://github.com/SpongeBob-G ...
- Linux下一个C基本的编程----写进Blog在那之前
展望2周的实习吧. 各种酸甜苦辣.由于公司只是广告.毛承保让我去.严重的歧视.想也想开,争夺.结果让它成为.还是把它写自己的学习经验,我有同样的希望和迷茫的同学.少走一点弯路.行.切入正题: 一.參考 ...
- 安裝 Rails 開發環境
安裝 Rails 開發環境 Give someone a program, you frustrate them for a day; teach them how to program, you f ...
- LCD开发之汉字显示
一.LCD显示原理 利用液晶制成的显示器称为LCD,根据驱动方式可分为静态驱动.简单矩阵驱动以及主动矩阵驱动3种.当中,简单矩阵型又可再细分扭转向列型(TN)和超扭转式向列型(STN)两种,而主动矩阵 ...
- Cocos2d-x 2.3.3版本 FlappyBird
Cocos2d-x 2.3.3版本 FlappyBird 本篇博客基于Cocos2d-x 2.3.3, 介绍怎样开发一款之前非常火的一款游戏FlappyBird.本篇博客内容大纲例如以下: 1 ...
- 用javascript把扑克牌理理顺!
打扑克的人都知道,比如斗地主! 我们一般都会按照顺序把随机摸过来的牌从小到大的顺序在手上理整齐(记得小时候打牌两副牌手都抓不过来),这篇随笔就是想通过实现这个功能来熟悉下js中排序数组等相关知识. 用 ...
- 【Android中Broadcast Receiver组件具体解释
】
BroadcastReceiver(广播接收器)是Android中的四大组件之中的一个. 以下是Android Doc中关于BroadcastReceiver的概述: ①广播接收器是一个专注于接收广播 ...
- 附加没有LDF的数据库文件
原文:附加没有LDF的数据库文件 如果你只下载了数据文件,没有LDF文件,那么附加的时候选择使用ATTACH_REBUILD_LOG. 命令类似: USE [master] GO CREATE DAT ...
- TodoList开发笔记 – Part Ⅱ
上一节给出了应用的两个主要UML类图,应用采用的技术也给出了,这一节开始实际设计编码 一.应用公开的方法 其实就几个的方法而已 1.代办事项的CRUD 2.代办事项归类目录的CRUD 3.代表事项“已 ...
- .NET MVC4 实训记录之六(利用ModelMetadata实现资源的自主访问)
上一篇我们已经实现自定义资源文件的访问,该篇我们使用它配合ModelMetadata实现资源文件的自主访问.这样做是为了我们能更简单的用MVC原生的方式使用资源文件.由于我的文章旨在记录MVC项目的实 ...