iOS开发之UIWebView的常见一些用法
虽然现在Xcode8已经开始使用WKWebView这个框架进行网页展示,但是UIWebView也有一些常用的方法需要知道,下面就简单展示一下,仅供大家参考
相关知识:1.设置背景透明;2.加载本地HTML页面;3.移除滚动后的外边阴影;4.在Safari中打开链接地址;5.禁用页面滚动弹跳;6.scalesPageToFit属性;7.调用javascript代码;8.javascript调用native代码;9.让UIWebView更加接近native
设置背景透明
设置webview的backgroundColor属性为[UIColor clearColor];
webView.backgroundColor = [UIColor clearColor];为webview中的HTML页面的body标签添加CSS背景样式设置
<body style="background-color: transparent"> ... </body>设置webview的opaque属性值为NO
webView.opaque = NO;
加载本地HTML页面
方式一
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]];
方式二
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实现的,因此移除这种阴影效果的代码如下:
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 ;
}
}
在Safari中打开链接地址
默认情况下,长按web页面中的链接,系统会自动呼出菜单提供open,copy和cancel选项,但如果要实现触击链接跳转至safari中打开页面该怎么做呢?UIWebViewDelegate协议中,包含
- (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:接口
- (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属性即可获得该对象,默认情况下网页长度超出设备视口长度后页面会滚动,用户使用手指滚动页面到页面边距并放开手指后页面会产生一个弹跳效果,去除这个效果的方法如下
webView.scrollView.bounces = NO ;
参见:Stop UIWebView from “bouncing” vertically?
scalesPageToFit属性
默认情况下UIWebView加载HTML页面后,会以页面的原始大小进行显示,亦即如果页面的大小超出UIWebView视口大小,UIWebView会出现滚动效果,而且用户只能通过滚动页面来查看不同区域的内容,不能使用手指的捏合手势来放大或缩小页面。通过设置
webView.scalesPageToFit = YES ;
UIWebView可以缩放HTML页面来适配其视口大小,从而达到整屏显示内容的效果,并且用户可以用捏合动作来放大或缩小页面来查看内容。
调用javascript代码
UIWebView提供
- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script
方法,可以在objective-c代码中调用javascript代码,参数script字符串保存了所要执行的js代码字符串,执行结果以字符串形式返回。以获取web页面标题为例,代码如下:
NSString *pageTitle = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
脚本的代码内容还要依据具体的应用场景。此外,该方法规定执行的脚本时长限定在10s内,为的是防止过长时间的阻塞页面主线程,超过执行时间上线会自动停止脚本运行,并且脚本可分配内存限定在10MB内,超过分配上线将会引发异常。
javascript调用native代码
以上提到,UIWebView加载任何一个页面之前都会调用其代理的
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
方法,通过调用参数request对象的URL属性来获取关于本次请求的地址以及参数信息,因此可以通过js代码模拟一次特殊的网络请求来达到调用该代理方法的作用,并通过过滤“特殊的url”来达到有目的性的js代码调用native代码的效果。所谓的“特殊的url”主要的目的是达到一种标识的效果,我们可以规定url的scheme部分,如appscheme://appName?invokeMethodName=objcMethod¶mA=xxx;也可以在常规的url后面附加特殊的参数标识,如http://www.yoursite.com?objecMethodCallFlag=1&methodName=methodA¶mA=xxx。之后根据规定在代理方法中去相应的解析url并做出if else判断即可。常见的调用方式是动态添加一个隐藏的iframe标签到HTML页面,如下:
// 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¶mA=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代码
.disable-callout{ -webkit-touch-callout:none ; }或在webViewDidFinisheLoad中使用
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];-webkit-user-select
控制用户是否可以选择页面元素内容。IOS中,在页面元素中进行长按操作,safari会弹出菜单,来允许进行选择行为。禁用此行为代码
.disable-select{ -webkit-user-select:none; }或在webViewDidFinisheLoad中使用
[webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
-webkit-tap-highlight-color
覆盖当用户tap链接或clickable元素时默认产生的高亮颜色(灰色)。如
.no-highlight{ -webkit-tap-highlight-color:rgba(0,0,0,0); }
iOS开发之UIWebView的常见一些用法的更多相关文章
- iOS开发之UIWebView
转自:http://www.cnblogs.com/zhuqil/archive/2011/07/28/2119923.html UIWebView是iOS sdk中一个最常用的控件.是内置的浏览器控 ...
- iOS开发之UIWebView自动滑动到顶部-备
但可以通过subview来操作. 通常用UIWebView加载网页,有时候需要点击一个按钮,或者页面的某个部位,使页面自动滚动到顶部,但是UIWebView不像UIScrollView那么方便. ...
- iOS开发之UIView的常见属性
1.所有控件都继承自UIView,UIView的常见属性如下: @property(nonatomic,readonly) UIView *superview;获得自己的父控件对象 @property ...
- 李洪强iOS开发之FMDB线程安全的用法
// // ViewController.m // 04 - FMDB线程安全的用法 // // Created by 李洪强 on 2017/6/6. // Copyright © 2017 ...
- iOS开发之cell位置contentOffset的用法
@property(nonatomic) CGPoint contentOffset; // default ...
- iOS开发之Socket通信实战--Request请求数据包编码模块
实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncS ...
- iOS开发之loadView、viewDidLoad及viewDidUnload的关系
iOS开发之loadView.viewDidLoad及viewDidUnload的关系 iOS开发之loadView.viewDidLoad及viewDidUnload的关系 标题中所说的3个方 ...
- iOS开发之info.pist文件和.pch文件
iOS开发之info.pist文件和.pch文件 如果你是iOS开发初学者,不用过多的关注项目中各个文件的作用.因为iOS开发的学习路线起点不在这里,这些文件只会给你学习带来困扰. 打开一个项目,我们 ...
- iOS 开发之Block
iOS 开发之Block 一:什么是Block.Block的作用 UI开发和网络常见功能的实现回调,按钮事件的处理方法是回调方法. 1. 按钮事件 target action 机制. 它是将一 ...
随机推荐
- 多线程利器---队列(queue)
列表是不安全的数据结构 import threading,time li=[1,2,3,4,5] def pri(): while li: a=li[-1] print(a) time.sleep(1 ...
- Css实现checkbox及radio样式自定义
前言 checkbox和radio样式自定义在网页中是很常见的, 比如在进行表单输入时性别的选择,用户注册时选择已阅读用户协议.随着用户对产品体验要求越来越高,我们都会对checkbox和radio重 ...
- python 网路爬虫(二) 爬取淘宝里的手机报价并以价格排序
今天要写的是之前写过的一个程序,然后把它整理下,巩固下知识点,并对之前的代码进行一些改进. 今天要爬取的是淘宝里的关于手机的报价的信息,并按照自己想要价格来筛选. 要是有什么问题希望大佬能指出我的错误 ...
- BZOJ 3938 Robot
Description 小q有n只机器人,一开始他把机器人放在了一条数轴上,第i只机器人在ai的位置上静止,而自己站在原点.在这 之后小q会执行一些操作,他想要命令一个机器人向左或者向右移动x格.但是 ...
- [HNOI2001]求正整数
题目描述 对于任意输入的正整数n,请编程求出具有n个不同因子的最小正整数m. 例如:n=4,则m=6,因为6有4个不同整数因子1,2,3,6:而且是最小的有4个因子的整数. 输入输出格式 输入格式: ...
- 洛谷mNOIP模拟赛Day2-星空
题目背景 pdf题面和大样例链接:http://pan.baidu.com/s/1cawM7c 密码:xgxv 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷. 你来过,然后你走后,只留下星空. ...
- Linux 虚拟内存和物理内存的理解(转)
在学习内核之前,因为虚拟内存的关系看过这篇文章,但是有的地方不是很懂. 现在对内核学习一段时间后,感觉这篇博客不错. 虚拟内存: 第一层理解 1.每个进程都有自己独立的4G内存空间,各个进程的内存空间 ...
- bzoj 1217: [HNOI2003]消防局的设立
Description 2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地.起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了 ...
- VLAN的划分
VLAN划分是指逻辑上把网络资源和网络用户按照一定的原则进行划分,把一个物理上实际的网络划分成多个小的逻辑网络.设计VLAN的最初目的是隔离局域网的广播,不让它去影响网络带宽.VLAN与传统的LAN相 ...
- 一个小小的抽奖活动测试脚本(python2.7)
# coding=utf-8import requestsimport cx_Oracletns=cx_Oracle.makedsn('172.30.0.155',1521,'szdev')db1=c ...