Skip to content

Latest commit

 

History

History
120 lines (90 loc) · 5.96 KB

9.UI基础之UIWebView.md

File metadata and controls

120 lines (90 loc) · 5.96 KB

9.UI基础之UIWebView

在iOS 8之前,在应用中嵌入网页会使用到UIWebView这个类,UIWebView也是继承自UIView的视图类,因此,其主要作用是将HTML文本渲染成网页界面或者通过一个网页链接来渲染界面。随着应用程序对网页与原生界面交互要求的加大,UIWebView越来越难以满足开发者的需求,因此在iOS 8之后,系统引入了UIWebKit框架,其大大增强了网页与原生的交互能力,对开发者来说,在进行嵌入网页相关功能的开发的同时也更加结构化。

由于iOS 9之后和Xcode 7之后的版本默认网络请求将使用Https协议类型,若要支持Http协议,需要在Info.plist文件中配置相关参数。Info.plist文件用于对工程进行一些功能配置,使用Xcode创建任何一个工程时都会默认生成一个Info.plist配置文件,如图15-26所示。向Info.plist文件中添加一个配置项App Transport SecuritySettings,向其中添加一个Boolean类型的键Allow ArbitaryLoads,设置为YES,这个键的作用是允许项目支持Http类型的网络请求。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let webView = UIWebView(frame: self.view.bounds)
        // 创建网页url
        let url = URL(string: "https://www.baidu.com")
        // 创建请求
        let request = URLRequest(url: url!)
        // 加载网页
        webView.loadRequest(request)
        self.view.addSubview(webView)
    }
}
class ViewController: UIViewController, UIWebViewDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        let webView = UIWebView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: self.view.bounds.size.height))
        
        self.view.addSubview(webView)
        webView.delegate = self
        let url = URL(string: String("http://www.baidu.com"))
        let request = URLRequest(url: url!)
        webView.loadRequest(request)
        // 让网页自动使用大小
        webView.sizeToFit()
        webView.sizeThatFits(self.view.bounds.size)
        // 网页收缩适配
        webView.scalesPageToFit = true
        // 是否使用内联播放器
        webView.allowsInlineMediaPlayback = true
    }
    
    func webViewDidStartLoad(_ webView: UIWebView) {
        print("start load")
    }
    // 网页加载失败时
    func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {
        print("did load error")
    }
    func webViewDidFinishLoad(_ webView: UIWebView) {
        print("load finish")
    }
    // 网页发起请求前,询问是否可以发起请求
    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
        return true
    }
}

这里需要注意一下,以为牵扯到联网所有要声明网络权限,在info.plist右键选择Open As Source Code,然后在节点的最下面加上

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

类似Android中在Manifest文件中添加Internet权限一样。

对于简单的网页嵌入需求,使用UIWebView已经足够,但是对于更加复杂的需求,例如在网页与原生交互十分频繁的场景中,UIWebView处理起来就有些力不从心。iOS8之后,系统引入了WebKit框架,将应用中嵌入网页的相关接口提取整合成了一个完整的框架,WebKit框架中添加了一些原生与JavaScript交互的方法,并且WebKit框架中采用导航栈的模型进行网页的跳转管理,开发者可以更加容易地控制和管理网页的渲染。WebKit框架中设计的类很多,框架的设计非常面向对象化,也非常模块化,这也更有利于开发者代码的结构化。

WebKit框架中最核心的类应该属于WKWebView类,这个类专门用来进行网页视图的渲染,其需要通过WKWebViewConfiguration类来进行配置。WKWebViewConfiguration类中主要包含3个模块:WKPreferences用于进行自定义的偏好配置,WKProcesssPool类用于进程池的配置,WKUserContentController类也是一个核心类,其主要用来做native与JavaScript的交互管理。关于WKUserContentController,其又需要两个类的协作,WKUserScript类用于通过原生代码向网页注入JavaScript代码,WKScriptMessageHandler类用于处理JavaScript代码调用的原生方法。除了前面提到的这些类外,开发者可以通过WKNavigationDelegate协议监听网页的活动,WKNavigationAction类是某个活动的实例化对象,WKUIDelegate协议用于处理JavaScript代码中的一些弹出框事件,WKBackForwardList类用于栈结构的管理,WKBackForwardListItem类是每个网页节点的实例化对象。

首先在ViewController.swift文件中引入WebKit框架,如下所示:

import UIKit
import WebKit

class ViewController: UIViewController {
    var wkView: WKWebView?
    override func viewDidLoad() {
        super.viewDidLoad()
        // 创建网页配置
        let configuration = WKWebViewConfiguration()
        // 对网页视图进行实例化
        wkView = WKWebView(frame: self.view.frame, configuration: configuration)
        self.view.addSubview(wkView!)
        let url = URL(string: "https://www.baidu.com")
        let request = URLRequest(url: url!)
        wkView!.load(request)
    }
}