Skip to content

Instantly share code, notes, and snippets.

@christopherhelf
Last active November 19, 2021 18:00
Show Gist options
  • Save christopherhelf/1640454bcace39a87c93 to your computer and use it in GitHub Desktop.
Save christopherhelf/1640454bcace39a87c93 to your computer and use it in GitHub Desktop.
WKWebview Screenshots & Loading/Progress Notification
//
// WKWebViewPlus.swift
//
// Created by Christopher Helf on 19.09.15.
// Copyright © 2015 Christopher Helf. All rights reserved.
//
import Foundation
import UIKit
import WebKit
@objc protocol WKWebViewPlusDelegate {
optional func webViewReady()
optional func webViewProgress(progress: Double)
optional func webViewScreenshot(view: UIView)
}
class WKWebViewPlus : WKWebView, WKNavigationDelegate {
var statusDelegate : WKWebViewPlusDelegate?
var originalNavigationDelegate : WKNavigationDelegate?
var useSnapShot : Bool = false
override init(frame: CGRect, configuration: WKWebViewConfiguration) {
super.init(frame: frame, configuration: configuration)
self.initDelegates()
self.initViewportScript()
}
init(frame: CGRect) {
super.init(frame: frame, configuration: WKWebViewConfiguration())
self.initDelegates()
self.initViewportScript()
}
private func initDelegates() {
self.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil)
self.originalNavigationDelegate = self.navigationDelegate
self.navigationDelegate = self
}
private func initViewportScript() {
let viewPortjs = "var myCustomViewport = 'width=\(self.frame.size.width)px'; var viewportElement = document.querySelector('meta[name=viewport]');if (viewportElement) {viewportElement.content = myCustomViewport;} else {viewportElement = document.createElement('meta'); viewportElement.name = 'viewport'; viewportElement.content = myCustomViewport;}"
let webViewUserScriptViewPort = WKUserScript(
source: viewPortjs,
injectionTime: WKUserScriptInjectionTime.AtDocumentEnd,
forMainFrameOnly: true
)
self.configuration.userContentController.addUserScript(webViewUserScriptViewPort)
}
private func webViewReady() {
self.scrollView.unloadSwizzle()
statusDelegate?.webViewReady?()
makeScreenshot()
}
func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) {
self.scrollView.loadSwizzle()
}
private func webViewProgress(progress: Double) {
statusDelegate?.webViewProgress?(progress)
}
private func makeScreenshot() {
guard let _delegate = statusDelegate else {
return
}
var view: UIView!
if self.useSnapShot {
view = self.snapshotViewAfterScreenUpdates(true)
} else {
UIGraphicsBeginImageContextWithOptions(self.frame.size, false, 0.0)
self.drawViewHierarchyInRect(self.frame, afterScreenUpdates: true)
let snapshot = UIGraphicsGetImageFromCurrentImageContext()
view = UIImageView(image: snapshot)
view.frame = self.frame
}
dispatch_async(dispatch_get_main_queue()) {
_delegate.webViewScreenshot?(view)
}
}
override func observeValueForKeyPath(keyPath: String?, ofObject: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if keyPath == "estimatedProgress" {
self.webViewProgress(self.estimatedProgress)
}
}
deinit {
self.removeObserver(self, forKeyPath: "estimatedProgress")
}
}
extension UIScrollView {
func swizzleMethod(originalSelector: Selector, swizzledMethod: Selector){
let original = class_getInstanceMethod(object_getClass(self), originalSelector)
let swizzled = class_getInstanceMethod(object_getClass(self), swizzledMethod)
method_exchangeImplementations(original, swizzled);
}
func loadSwizzle() {
self.swizzleMethod(Selector("setContentSize:"), swizzledMethod: ("setContentSizeSwizzled:"))
}
func unloadSwizzle() {
self.swizzleMethod(Selector("setContentSizeSwizzled:"), swizzledMethod: ("setContentSize:"))
}
func setContentSizeSwizzled(contentSize : CGSize) {
self.setContentSizeSwizzled(contentSize)
if let webview = self.superview as? WKWebViewPlus {
if contentSize.height != 0 && contentSize.width != 0 {
webview.webViewReady()
}
}
}
}
@ChokWah
Copy link

ChokWah commented Mar 15, 2016

If it has a demo , it will be more helpful .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment