Created
March 13, 2017 16:58
-
-
Save ejmartin504/58e0a913d28ce229fcccfb0194eff604 to your computer and use it in GitHub Desktop.
WKWebView that resizes itself
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import WebKit | |
// See https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns.html for more details. | |
private var observerContext = 0 | |
class StackableWebView: WKWebView { | |
// Keep track of height which will change when the view is loaded. | |
var webViewHeight: CGFloat = 0.0 | |
init(frame: CGRect) { | |
let config = WKWebViewConfiguration() | |
let preferences = WKPreferences() | |
config.preferences = preferences | |
super.init(frame: frame, configuration: config) | |
} | |
required init?(coder: NSCoder) { | |
super.init(coder: coder) | |
} | |
func setup() { | |
addObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), options: .new, context: &observerContext) | |
scrollView.isScrollEnabled = false | |
scrollView.scrollsToTop = false | |
scrollView.showsVerticalScrollIndicator = false | |
scrollView.showsHorizontalScrollIndicator = false | |
} | |
override var intrinsicContentSize: CGSize { | |
var size = super.intrinsicContentSize | |
size.height = webViewHeight | |
return size | |
} | |
deinit { | |
removeObserver(self, forKeyPath: #keyPath(WKWebView.estimatedProgress), context: &observerContext) | |
} | |
} | |
extension StackableWebView { | |
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { | |
if context == &observerContext { | |
if let _ = change?[.newKey] as? Double { | |
guard self.estimatedProgress > 0.5 else { return } | |
let js = "document.getElementsByTagName('html')[0].offsetHeight" | |
self.evaluateJavaScript(js, completionHandler: { result, error in | |
let contentHeight = result as? CGFloat ?? 0.0 | |
if contentHeight > self.webViewHeight { | |
print("setting height to \(contentHeight)") | |
self.webViewHeight = contentHeight | |
self.invalidateIntrinsicContentSize() | |
} | |
}) | |
} | |
} else { | |
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment