WebView和Html
说说WebView如何加载Html,css以及javascript
说一个网易新闻的实例:
通过一个Http请求获得要加载的Html页面数据:
extension ViewController {
//请求网易新闻页数据
func webRequest() {
let url = URL(string: "http://c.m.163.com/nc/article/BJ5NRE5T00031H2L/full.html")
let request = URLRequest(url: url!)
let session = URLSession.shared
let task:URLSessionDataTask = session.dataTask(with: request) { (data, response, error) in
guard error == nil else {
return
}
//print(NSString.init(data: data!, encoding: String.Encoding.utf8.rawValue)!)
let jsonData = try? JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments)
let dataDict = jsonData as! [String : Any]
self.showData(dict: dataDict)
}
task.resume()
}
//请求完毕后拼接html代码,另外新建css文件和js文件在本地
func showData(dict:[String : Any]) {
guard let allData = dict["BJ5NRE5T00031H2L"] as? [String : Any] else {
return
}
//print(allData)
guard var bodyHtml = allData["body"] as? String else {
return
}
guard let imgs = allData["img"] as? [[String : Any]] else {
return
}
for img in imgs {
let ref = img["ref"] as! String
let src = img["src"] as! String
let alt = img["alt"] as! String
let imageHtml = "<div class=\"imageDiv\"><img src=\"\(src)\" alt=\"\(alt)\"></div><div>\(alt)</div>"
bodyHtml = bodyHtml.replacingOccurrences(of: ref, with: imageHtml)
}
guard let ptimeStr = allData["ptime"] as? String else {
return
}
guard let titleStr = allData["title"] as? String else {
return
}
let titleHtml = "<div id=\"mainTitle\">\(titleStr)</div>"
guard let sourceStr = allData["source"] as? String else {
return
}
let subTitleHtml = "<div id=\"subTitle\"><span class=\"ptime\">\(ptimeStr)</span><span>\(sourceStr)</span></div>"
guard let cssPath = Bundle.main.url(forResource: "news.css", withExtension: nil) else {
return
}
let cssHtml = "<link href=\"\(cssPath)\" rel=\"stylesheet\">"
guard let jsPath = Bundle.main.url(forResource: "news.js", withExtension: nil) else {
return
}
let jsHtml = "<script src=\"\(jsPath)\"></script>"
let currentHtml = "<html><head><title>\(titleHtml)</title>\(cssHtml)\(jsHtml)</head><body>\(titleHtml)\(subTitleHtml)\(bodyHtml)</body></html>"
print(currentHtml)
webView.loadHTMLString(currentHtml, baseURL: nil)
}
}
先看看css和js中的内容
css
#mainTitle{
text-align:center;
font-size:20px;
margin-top:25px;
margin-bottom:8px;
}
#subTitle {
color:gray;
text-align:center;
}
img {
width: 100%;
}
.time{
margin-right:10px;
margin-bottom:8px;
}
.imageDiv {
text-align:center;
color:gray;
margin:8px 0;
}
js
window.onload = function() {
var images = document.getElementsByTagName('img');
console.log(images);
for(var i = 0; i < images.length; i++) {
//console.log(i + ":" + images[i]);
var image = images[i];
console.log(typeof image);
image.onclick = function () {
//alert('图片[' + this.alt + ']被点击');
//window.location.href = 'https://www.baidu.com';
window.location.href = 'flashloft://openCamera';
}
}
}
js定义了网页中的图片如果被点击,会执行事件函数。如果需要监听事件,需要设置UIWebView的Delegate
extension ViewController: UIWebViewDelegate {
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
//这个方法可以扑捉到当前webView的请求,如果方法返回false,webView不会进行任何跳转
print(request.url!.absoluteString)
//如果webView捕捉到一个自定义的请求,可以执行一些方法,比如打开相机或相册等,这里打开系统相册
checkMethod(urlStr: request.url!.absoluteString)
return true
}
//去除自定义请求的协议头,判断如果协议头包含‘flashloft://’,则去除协议头,根据剩下的字段转换成selector,找到对应的方法并执行
func checkMethod(urlStr:String) {
let urlHead = "flashloft://"
guard let urlHeadRange = urlStr.range(of: urlHead) else {
return
}
print(urlHeadRange)
if urlStr.contains(urlHead) {
let methodName = urlStr.substring(from: urlHeadRange.upperBound)
print(methodName)
let sel = NSSelectorFromString(methodName)
self.perform(sel)
}
}
}
访问相机的方法,记得在info.plist配置 Privacy - Photo Library Usage Description 权限
extension ViewController {
func openPhotos() {
let imagePickerVC = UIImagePickerController()
imagePickerVC.sourceType = .photoLibrary
present(imagePickerVC, animated: true, completion: nil);
}
}