当前位置:首页 » 《我的小黑屋》 » 正文

IOS 23 实现通用WebView控制器(WKWebView)

0 人参与  2024年10月23日 14:40  分类 : 《我的小黑屋》  评论

点击全文阅读


在项目中我们经常会在多个界面使用到WebView,所以本文对WebView进行封装,实现一个通用的WebView控制器。

实现效果

简单的Webview

实现逻辑

使用系统提供的WKWebView控件,外界通过传递网址,或者字符串进行显示。

1)创建WebView控制器SuperWebController,继承自BaseTitleController。

class SuperWebController: BaseTitleController {}

2)定义SuperWebController接收的两个参数uri和content。

class SuperWebController: BaseTitleController {    var uri:String?    var content:String?}

3)重写initViews(),设置SuperWebController内容布局为RelativeLayout,并添加标题栏右边的关闭按钮 和 webView控件,webView控件使用懒加载创建。

class SuperWebController: BaseTitleController {    var uri:String?    var content:String?    override func initViews() {        super.initViews()        initRelativeLayoutSafeArea()        //设置右侧按钮        addRightImageButton(R.image.close()!.withTintColor())        container.addSubview(webView)    }    /// 获取配置    static func defaultConfiguration() -> WKWebViewConfiguration {        let r = WKWebViewConfiguration()        if #available(iOS 10.0, *) {            r.mediaTypesRequiringUserActionForPlayback = .all        } else if #available(iOS 9.0, *){            r.requiresUserActionForMediaPlayback = false        }else{            r.mediaPlaybackRequiresUserAction = false        }        return r    }    lazy var webView: WKWebView = {        let r = WKWebView(frame: CGRect.zero, configuration: SuperWebController.defaultConfiguration())        r.tg_width.equal(.fill)        r.tg_height.equal(.fill)        return r    }()}

4)获取外界传入的数据,并设置到webview上。

class SuperWebController: BaseTitleController {    static let CONTENT_WRAPPER_START = "<!DOCTYPE html><html><head><title></title><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\"><style type=\"text/css\"> body{font-family: Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Arial,sans-serif;word-wrap: break-word;word-break: normal;} h2{text-align: center;} img {max-width: 100%;} pre{word-wrap: break-word!important;overflow: auto;}</style></head><body>"    static let CONTENT_WRAPPER_END = "</body></html>"    static let WEBVIEW_BASE_URL = "http://ixuea.com"    override func initDatum() {        super.initDatum()        if SuperStringUtil.isNotBlank(uri) {            //显示网址内容            //创建一个Request            let request = URLRequest(url: URL(string: uri)!)            //请求            webView.load(request)        } else {            //显示字符串            //由于服务端,返回的字符串,不是一个完整的HTML字符串            //同时本地可能希望添加一些字体设置,所以要前后拼接为一个            //完整的HTML字符串            var buffer = String(SuperWebController.CONTENT_WRAPPER_START)            //添加内容            buffer.append(content!)            buffer.append(SuperWebController.CONTENT_WRAPPER_END)            //加载字符串            webView.loadHTMLString(buffer, baseURL: URL(string: SuperWebController.WEBVIEW_BASE_URL))        }    }}

5)拦截返回按钮事件和添加关闭页面事件

class SuperWebController: BaseTitleController {        /// 拦截点击返回按钮    override func leftClick(_ sender: QMUIButton) {        if webView.canGoBack {            //如果浏览器能返回上一页,就直接返回上一页            webView.goBack()            return        }        super.leftClick(sender)    }    override func rightClick(_ sender: QMUIButton) {        finish()    }    /// 关闭界面    func finish() {        navigationController?.popViewController(animated: true)    }}

6)扩展一个start方法,提供给外界启动webview。

extension SuperWebController{    /// 启动方法    static func start(_ controller:UINavigationController,title:String?=nil,uri:String?=nil,content:String?=nil) {        let target = SuperWebController()        target.title = title        target.uri=uri        target.content = content        controller.pushViewController(target, animated: true)    }}

7)使用webview

SuperWebController.start(navigationController!,title: data.title,uri: data.uri)

至此,简单的webview就实现了,下面继续封装 动态网页标题和进度功能。

动态标题和进度Webview

实现逻辑

如果外界没有传递标题,就显示网页标题;仿微信内部的浏览器顶部的进度条,这里要实现类似功能。进度条控件使用UIProgressView,然后监听webView进度,并设置到进度条。

1)给SuperWebController添加UIProgressView,UIProgressView控件使用懒加载创建。

class SuperWebController : BaseTitleController{        override func initViews() {        super.initViews()        initRelativeLayoutSafeArea()                //设置右侧按钮        addRightImageButton(R.image.close()!.withTintColor())                container.addSubview(webView)                container.addSubview(progressView)    }    lazy var progressView: UIProgressView = {        let r = UIProgressView()        r.tg_width.equal(.fill)        r.tg_height.equal(1)                //设置进度条的颜色        r.progressTintColor = .colorPrimary        return r    }()}

2)添加标题和进度监听

class SuperWebController : BaseTitleController{        override func initListeners() {        super.initListeners()        if SuperStringUtil.isBlank(title){            //监听网页标题            webView.addObserver(self, forKeyPath: "title", options: .new,context: nil)        }                //监听加载进度        webView.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)    }}

3)重写KVO监听回调,动态更新标题和进度条。

class SuperWebController : BaseTitleController{    /// KVO监听回调    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {        if let _ = object as? WKWebView{            if keyPath == "title"{                //标题                title = webView.title            }else if keyPath == "estimatedProgress"{                //进度                                //0~1                let progress = change?[.newKey] as? Float ?? 0                progressView.progress = progress                                if progress < 1 {                    progressView.show()                                        //完全不透明                    progressView.alpha = 1                }else{                    UIView.animate(withDuration: 0.35, delay: 0.15) {                        self.progressView.alpha = 0                    } completion: { finished in                        if finished {                            self.progressView.hide()                            self.progressView.progress=0                            self.progressView.alpha = 1                        }                    }                }            }        }    }    }

至此,动态网页标题和进度功能的webview就实现了。


点击全文阅读


本文链接:http://zhangshiyu.com/post/176209.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1