1、本来有用IQKeyboardManager第三方,但用了后老是有些小BUG,于是还不如自己写几行代码,不然真的很烦
2、webView或wkWebView加载网页时,如果不加一个蒙板,点击键盘外部无法关闭键盘(不知是不是和网页中的点击事件冲突,还不是很明白原理),于是加了个蒙板了 ...
3、补充加载进度条
4、若有全局返回手势 得把estimatedProgress观察者放在viewWillAppear
代码如下:
//
// DetailViewController.swift
// WebViewDemo
//
// Created by apiapia on 9/10/17.
// Copyright © 2017 ELINKNET.CN. All rights reserved.
//
import UIKit
import WebKit
import IQKeyboardManager
class DetailViewController: UIViewController,WKUIDelegate,WKNavigationDelegate,UITextFieldDelegate {
var urlString:String = "http://www.jianshu.com/p/260985a528f7?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=qq"
@IBOutlet weak var grayView: UIView!
@IBAction func bgTap(_ sender: UIControl) {
self.view.endEditing(true)
}
@IBOutlet weak var bottomConstrain: NSLayoutConstraint!
@IBOutlet weak var textField: UITextField!
// wkWebView
lazy var wkWebView: WKWebView = {
var webView = WKWebView(frame: self.view.bounds)
let url = URL(string: self.urlString)
webView.load(URLRequest(url: url!))
webView.uiDelegate = self
webView.navigationDelegate = self
webView.isUserInteractionEnabled = true
return webView
}()
//进度条
lazy var progressView:UIProgressView = {
let progressView = UIProgressView(frame: CGRect(x: 0, y: 64, width: self.view.frame.width, height: 1))
progressView.progressTintColor = UIColor.green
progressView.trackTintColor = UIColor.lightGray
return progressView
}()
override func viewDidLoad() {
super.viewDidLoad()
grayView.isHidden = true
grayView.alpha = 0.5
IQKeyboardManager.shared().isEnabled = false
self.view.insertSubview(wkWebView, at: 0)
self.view.addSubview(progressView)
self.wkWebView.addObserver(self, forKeyPath: "estimatedProgress", options: NSKeyValueObservingOptions.new, context: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// 以下代码放在 deinit就崩溃 weird
wkWebView.removeObserver(self, forKeyPath: "estimatedProgress")
wkWebView.uiDelegate = nil
wkWebView.navigationDelegate = nil
}
deinit {
NotificationCenter.default.removeObserver(self) // 移除键盘的
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
// 键盘
extension DetailViewController {
func keyboardShow(_ note: NSNotification) {
let userInfo = note.userInfo!
let duration = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
UIView.animate(withDuration: duration, animations: {
self.grayView.alpha = 0.0
}) { (true) in
self.grayView.alpha = 0.5
self.grayView.isHidden = false
}
// 键盘弹出的frame
let keyboardRect:CGRect = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
self.view.frame = CGRect(x: 0, y: -keyboardRect.size.height, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}
func keyboardHide(_ note: NSNotification) {
let userInfo = note.userInfo!
let duration = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
UIView.animate(withDuration: duration, animations: {
self.grayView.alpha = 0.5
}) { (true) in
self.grayView.alpha = 0.0
self.grayView.isHidden = true
}
self.view.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
}
// 点击键盘外部关闭
func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
UIApplication.shared.keyWindow?.endEditing(true)
}
}
// 进度条
extension DetailViewController {
// KVO
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "estimatedProgress" {
self.progressView.alpha = 1.0
progressView.setProgress(Float(self.wkWebView.estimatedProgress), animated: true)
if(self.wkWebView.estimatedProgress >= 1.0) {
UIView.animate(withDuration: 0.3, delay: 0.1, options: UIViewAnimationOptions.curveEaseInOut, animations: { () -> Void in
self.progressView.alpha = 0.0
}, completion: { (finished:Bool) -> Void in
self.progressView.progress = 0
})
}
}
}
//防止progressView被网页挡住
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
self.view.bringSubview(toFront: self.progressView)
}
//加载完成
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.progressView.isHidden = true
}
//加载失败
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
self.progressView.isHidden = true
}
}
补充:不知为何有一个BUG,就是下面的这个代码有时候移植的时候,点击键盘外部不响应,无法正常关闭键盘
// 点击键盘外部关闭
func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
UIApplication.shared.keyWindow?.endEditing(true)
// super.touchesBegan(touches, with: event)
next?.touchesBegan(touches, with: event)
printLog("点击键盘外部关闭")
textView.resignFirstResponder()
}
如果遇到上面这个问题,其实也不要紧,只要在 grayView加上一个点击手势就行了
// MARK: -- 填加单击手势
self.grayView.isUserInteractionEnabled = true
var tap = UITapGestureRecognizer()
tap = UITapGestureRecognizer(target: self, action: #selector(keyboardResignFirst))
tap.numberOfTapsRequired = 1
self.grayView.addGestureRecognizer(tap)
func keyboardResignFirst() {
// printLog("weird")
textView.resignFirstResponder()
}