UIWebView用法详解及代码分享



今天加入一个QQ群,也算是一个圈子,群主的要求是满足他的三个条件。经过与群主的沟通,终于得到通过,顺利加入。

群主是一个93年的小伙,而且是河南的老乡。没想到小伙子这么有号召力。我也是偶然在我的空间发现他的,看他每天发的文章,还挺有意思。

90后的小伙子都这么厉害了,有什么理由不努力奋斗呢!多加入以下圈子,认识一下身边的牛人。说不定会有意外的收获。

今天我们来详细UIWebView用法。UIWebView是iOS内置的浏览器控件,可以浏览网页、打开文档等 能够加载html/htm、pdf、docx、txt等格式的文件.

用UIWebView我们就可以做一个简易的浏览器。效果如下:

创建UIWebView

首先创建UIWebView,这个不难,设置frame,然后添加到self.view上即可:

UIWebView *webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
webView.scalesPageToFit = YES;//自动对页面进行缩放以适应屏幕
[self.view addSubview:webView];

UIWebView加载网络地址

用UIWebView来加载网络地址,那我的博客:http://www.superqq.com 来举例。代码如下:

NSURLRequest *request =[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.superqq.com"]];
[self.view addSubview:webView];
[webView loadRequest:request];

UIWebView加载本地资源

通过NSURLRequest加载

NSString *path = [[NSBundle mainBundle] pathForResource:@"swift" ofType:@"html"];
NSURL* url = [NSURL   fileURLWithPath:path];//创建URL
NSURLRequest* request = [NSURLRequest requestWithURL:url];//创建NSURLRequest
[webView loadRequest:request];//加载

通过NSString加载

UIWebView 还支持将一个NSString对象作为源来加载。你可以为其提供一个基础URL,来指导UIWebView对象如何跟随链接和加载远程资源:

NSString *path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
NSString *htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[webView loadHTMLString:htmlString baseURL:[NSURL URLWithString:path]];

自动检测电话

设置这个属性,如果在加载的网页中遇到电话号码,直接单击就可以拨打,非常方便:

webView.dataDetectorTypes = UIDataDetectorTypePhoneNumber;//自动检测网页上的电话号码,单击可以拨打

设置代理和代理方法

UIWebView有五个代理方法,我们可以在不同的代理方法中,完成不同的需求。

//设置代理
webView.delegate = self;

//代理方法
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    //返回YES,进行加载。通过UIWebViewNavigationType可以得到请求发起的原因
    return YES;
}

- (void)webViewDidStartLoad:(UIWebView *)webView
{
    //开始加载,可以加上风火轮(也叫菊花)
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    //完成加载
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    //加载出错
}

创建加载他、停止、后退、前进按钮

创建四个按钮,分别是加载按钮、停止按钮、返回按钮、前进按钮:

NSArray *array = [NSArray arrayWithObjects:@"加载",@"停止",@"返回",@"前进", nil];
    int far = (SCREEN.width - 200)/5;
    for (int i = 0; i < array.count; i++) {
        UIButton *button = [[UIButton alloc] init];
        button.frame = CGRectMake( (i + 1) * far + 50 * i, SCREEN.height - 60, 50, 40);
        button.tag = 200 + i;
        [button addTarget:self action:@selector(actionClick:) forControlEvents:UIControlEventTouchUpInside];
        [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
        [button setBackgroundColor:[UIColor orangeColor]];
        [button setTitle:array[i] forState:UIControlStateNormal];
        [self.view addSubview:button];
    }

前进后退

给四个按钮绑定事件,根据tag值来区分每一个点击事件:

- (void)actionClick:(UIButton *)button
{
    switch (button.tag) {
        case 200:
        {
            [self.webView reload];//加载
        }
            break;
        case 201:
        {
            [self.webView stopLoading];//停止加载
        }
            break;
        case 202:
        {
            [self.webView goBack];//返回
        }
            break;
        case 203:
        {
            [self.webView goForward];//前进
        }
            break;
        default:
            break;
    }
}

大功告成,再来看看效果:

以上分享的内容我做了一个demo,需要的话可以点击这里下载:https://github.com/worldligang/UIWebViewDemo


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
有用的控件,经常使用设置背景透明 设置webview的backgroundColor属性为[UIColor clearColor]; ? 1 webView.backgroundColor = [UIColor clearColor]; 为webview中的HTML页面的body标签添加CSS背景样式设置 ? 1 2 3 <body style="background-color: transparent"> ... </body> 设置webview的opaque属性值为NO ? 1 webView.opaque = NO; 加载本地HTML页面 方式一 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 NSString *localHTMLPageName = @"myPage"; NSString *path = [[NSBundle mainBundle] pathForResource:localHTMLPageName ofType:@"html"]; // 从html文件中读取html字符串 NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:path]; NSString *htmlString = [[NSString alloc] initWithData: [readHandle readDataToEndOfFile] encoding:NSUTF8StringEncoding]; // 或使用 // NSString *htmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL]; // baseURL用来确定htmlString的基准地址, // 相当于HTML的<base>标签的作用,定义页面中所有链接的默认地址。 [webView loadHTMLString:htmlString baseURL:[[NSBundle mainBundle] bundleURL]]; 方式二 ? 1 2 3 4 5 6 7 NSString *localHTMLPageName = @"myPage"; NSString *localHTMLPageFilePath = [[NSBundle mainBundle] pathForResource:localHTMLPageName ofType:@"html"]; NSURL *localHTMLPageFileURL = [NSURL fileURLWithPath:localHTMLPageFilePath]; [webView loadRequest:[NSURLRequest requestWithURL:localHTMLPageFileURL]]; 移除滚动后的外边阴影 UIWebView包含一个scrollView组件,用来将关联web内容实现滚动效果,页面滚动后的UIWebView的面板周围会出现阴影效果,该效果是在四周添加UIImageView实现的,因此移除这种阴影效果的代码如下: ? 1 2 3 4 5 6 7 8 UIScrollView *scrollView = webView.scrollView; for (int i = 0; i < scrollView.subviews.count ; i++) { UIView *view = [scrollView.subviews objectAtIndex:i]; if ([view isKindOfClass:[UIImageView class]]) { view.hidden = YES ; } } 参见Remove UIWebView Shadow? 在Safari中打开链接地址 默认情况下,长按web页面中的链接,系统会自动呼出菜单提供open,copy和cancel选项,但如果要实现触击链接跳转至safari中打开页面该怎么做呢?UIWebViewDelegate协议中,包含 ? 1 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 接口,如果为webView添加了delegate对象并实现该接口,那么在webView加载任何一个frame之前都会delegate对象的该方法,该方法的返回值用以控制是否允许加载目标链接页面的内容,返回YES将直接加载内容,NO则反之。并且UIWebViewNavigationType枚举,定义了页面中用户行为的分类,包括 UIWebViewNavigationTypeLinkClicked,用户触击了一个链接。 UIWebViewNavigationTypeFormSubmitted,用户提交了一个表单。 UIWebViewNavigationTypeBackForward,用户触击前进或返回按钮。 UIWebViewNavigationTypeReload,用户触击重新加载的按钮。 UIWebViewNavigationTypeFormResubmitted,用户重复提交表单 UIWebViewNavigationTypeOther,发生其它行为。 因此,实现用户触击UIWebView页面中的链接,并跳至Safari中打开链接页面的步骤如下: 定义实现UIWebViewDelegate协议的类MyWebViewDelegate(通常是由包含UIWebView的controller中实现UIWebViewDelegate协议)。 按如下方式实现webView:shouldStartLoadWithRequest:navigationType:接口 ? 1 2 3 4 5 6 7 8 9 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if ( navigationType == UIWebViewNavigationTypeLinkClicked ) { [[UIApplication sharedApplication] openURL:[request URL]]; return NO; } return YES; } 新建MyWebViewDelegate对象,并赋值给webView的delegate属性 参见:UIWebView open links in Safari 禁用页面滚动弹跳 之前提到UIWebView使用一个UIScrollView对象来关联web页面的内容,通过UIWebView的scrollView属性即可获得该对象,默认情况下网页长度超出设备视口长度后页面会滚动,用户使用手指滚动页面到页面边距并放开手指后页面会产生一个弹跳效果,去除这个效果的方法如下 ? 1 webView.scrollView.bounces = NO ; 参见:Stop UIWebView from “bouncing” vertically? scalesPageToFit属性 默认情况下UIWebView加载HTML页面后,会以页面的原始大小进行显示,亦即如果页面的大小超出UIWebView视口大小,UIWebView会出现滚动效果,而且用户只能通过滚动页面来查看不同区域的内容,不能使用手指的捏合手势来放大或缩小页面。通过设置 ? 1 webView.scalesPageToFit = YES ; UIWebView可以缩放HTML页面来适配其视口大小,从而达到整屏显示内容的效果,并且用户可以用捏合动作来放大或缩小页面来查看内容。 调用javascript代码 UIWebView提供 ? 1 - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script 方法,可以在objective-c代码中调用javascript代码,参数script字符串保存了所要执行的js代码字符串,执行结果以字符串形式返回。以获取web页面标题为例,代码如下: ? 1 NSString *pageTitle = [webView stringByEvaluatingJavaScriptFromString:@"document.title"]; 脚本的代码内容还要依据具体的应用场景。此外,该方法规定执行的脚本时长限定在10s内,为的是防止过长时间的阻塞页面主线程,超过执行时间上线会自动停止脚本运行,并且脚本可分配内存限定在10MB内,超过分配上线将会引发异常。 javascript调用native代码 以上提到,UIWebView加载任何一个页面之前都会调用其代理的 ? 1 2 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 方法,通过调用参数request对象的URL属性来获取关于本次请求的地址以及参数信息,因此可以通过js代码模拟一次特殊的网络请求来达到调用该代理方法的作用,并通过过滤“特殊的url”来达到有目的性的js代码调用native代码的效果。所谓的“特殊的url”主要的目的是达到一种标识的效果,我们可以规定url的scheme部分,如appscheme://appName?invokeMethodName=objcMethod&paramA=xxx;也可以在常规的url后面附加特殊的参数标识,如http://www.yoursite.com?objecMethodCallFlag=1&methodName=methodA&paramA=xxx。之后根据规定在代理方法中去相应的解析url并做出if else判断即可。常见的调用方式是动态添加一个隐藏的iframe标签到HTML页面,如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 // js function invokeObjc(url) { var iframe; iframe = document.createElement("iframe"); iframe.setAttribute("src", url); iframe.setAttribute("style", "display:none;"); document.body.appendChild(iframe); iframe.parentNode.removeChild(iframe); } var url = "appscheme://appName?invokeMethodName=objcMethod&paramA=xxx"; invokeObjc(url); // objc - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { static NSString *callScheme = @"appscheme"; static NSString *invokeMethodName = @"invokeMethodName"; NSString *scheme = request.URL.scheme ; if ([callScheme isEqualToString:scheme]) { NSString *query = request.URL.query ; NSArray *arr = [query componentsSeparatedByString:@"&"]; __block NSString *methodName = @"" ; NSMutableDictionary *params = [NSMutableDictionary new]; // 未考虑参数的解码操作 [arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSArray *kv =[obj componentsSeparatedByString:@"="]; if (kv) { if ([invokeMethodName isEqualToString: kv[0]]) { methodName = kv[1]; }else{ [params setObject:kv[1] forKey:kv[0]]; } } }]; // 获得方法名和参数之后,可以添加逻辑判断 NSLog(@"%@",methodName); NSLog(@"%@",params); return NO ; } return YES ; } 前面提到的native代码调用js代码的实现方式,结合两种实现方式即完成了js与native代码间的简单的通信操作。 让UIWebView更加接近native 某些情况下,我们既想要UIWebView加载web页面,又想使得所加载的页面的外观和操作行为更加接近native感觉。这时需要使用一些CSS样式来达到这些效果,这些CSS只适用于IOS中的Safari。 -webkit-touch-callout 禁用长按触控对象弹出的菜单。IOS中,当你长按一个触控对象时,如链接,safari会弹出包含链接信息的菜单。禁用此行为CSS代码 ? 1 2 3 .disable-callout{ -webkit-touch-callout:none ; } 或在webViewDidFinisheLoad中使用 ? 1 [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"]; -webkit-user-select 控制用户是否可以选择页面元素内容。IOS中,在页面元素中进行长按操作,safari会弹出菜单,来允许进行选择行为。禁用此行为代码 ? 1 2 3 .disable-select{ -webkit-user-select:none; } 或在webViewDidFinisheLoad中使用 ? 1 [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"]; -webkit-tap-highlight-color 覆盖当用户tap链接或clickable元素时默认产生的高亮颜色(灰色)。如 ? 1 2 3 .no-highlight{ -webkit-tap-highlight-color:rgba(0,0,0,0);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值