欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > IOS 23 实现通用WebView控制器(WKWebView)

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

2024/10/23 22:46:20 来源:https://blog.csdn.net/sziitjin/article/details/141897910  浏览:    关键词:IOS 23 实现通用WebView控制器(WKWebView)

在项目中我们经常会在多个界面使用到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) {//显示网址内容//创建一个Requestlet 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 = titletarget.uri=uritarget.content = contentcontroller.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 = .colorPrimaryreturn 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~1let progress = change?[.newKey] as? Float ?? 0progressView.progress = progressif progress < 1 {progressView.show()//完全不透明progressView.alpha = 1}else{UIView.animate(withDuration: 0.35, delay: 0.15) {self.progressView.alpha = 0} completion: { finished inif finished {self.progressView.hide()self.progressView.progress=0self.progressView.alpha = 1}}}}}}}

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com