make WKWebview real fullscreen on iPhone X (remove safe area from WKWebView
After a little try and error, this is the solution I came up with.
Subclass WKWebView and create a custom class. Overwrite safeAreaInsets
:
import Foundation
import WebKit
class FullScreenWKWebView: WKWebView {
override var safeAreaInsets: UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
}
iOS WKWebView Status Bar Padding
I solved this problem using autolayout constraints, Please check
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate {
var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
setupWebView()
let url = URL(string: "https://www.google.com")
let request = URLRequest(url: url!)
webView.load(request)
}
func setupWebView() {
let webConfiguration = WKWebViewConfiguration()
webView = WKWebView(frame:.zero , configuration: webConfiguration)
webView.uiDelegate = self
//view = webView
view.addSubview(webView)
webView.translatesAutoresizingMaskIntoConstraints = false
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0":webView]))
view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-20-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0":webView]))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Hope it helps.
WKWebView: document.body.offsetHeight returns wrong height, why?
You Need to add meta tag as follows
<meta name=\"viewport\" content=\"initial-scale=1, user-scalable=no, width=device-width\" />
Can't get WKWebView content height correctly
following method should do a trick
//to get height
webView.evaluateJavaScript("document.height") { (result, error) in
if error == nil {
print(result)
}
}
//to get width
webView.evaluateJavaScript("document.width") { (result, error) in
if error == nil {
print(result)
}
}
// to get contentheight of wkwebview
func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
println(webView.scrollView.contentSize.height)
}
How to adjust WKWebview's container content height to the webview content?
I think you are actually pretty close to a solution there. I've faced a similar problem and managed to solve it with evaluating javascript. Our implementation is a little bit different since we use a stackview with nested WkWebViews as arranged subviews. But I can share our code (stripped out the stackview parts) and you can try it out yourself.
func addAndLoadWebView(with url: URL) {
let wkWebView = WKWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 100))
wkWebView.translatesAutoresizingMaskIntoConstraints = false
wkWebView.navigationDelegate = self
wkWebView.scrollView.isScrollEnabled = false
wkWebView.scrollView.bounces = false
wkWebView.scrollView.bouncesZoom = false
wkWebView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.view.addSubview(wkWebView)
wkWebView.load(URLRequest(url: url))
}
@available(iOS 12.0, *)
func asyncGetHTMLHeight(_ webview: WKWebView, completion: @escaping (CGFloat) -> Void) {
webview.evaluateJavaScript("document.body.offsetHeight") { (result, _) in
guard let result = result as? CGFloat else {
completion(0.0)
return
}
completion(result)
}
}
@available(iOS 12.0, *)
func compatibleMeasureImageContent(with webview: WKWebView) {
webview.evaluateJavaScript("document.body.firstChild.offsetHeight") { (result, _) in
guard let result = result as? CGFloat else {
return
}
var height = result
webview.evaluateJavaScript("document.body.firstChild.width") { (result, _) in
guard let width = result as? CGFloat else {
return
}
// do something with width and height here
// in our case images come 1 by one since our html is delivered in parts. You might have to check each image tag for its height for this calculation to work.
}
}
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.asyncGetHTMLHeight(webView, completion: { newHeight in
webView.frame.size.height = newHeight
webView.removeConstraints(webView.constraints)
webView.heightAnchor.constraint(equalToConstant: newHeight).isActive = true
})
}
How to determine the content size of a WKWebView?
I think I read every answer on this subject and all I had was part of the solution. Most of the time I spent trying to implement KVO method as described by @davew, which occasionally worked, but most of the time left a white space under the content of a WKWebView container. I also implemented @David Beck suggestion and made the container height to be 0 thus avoiding the possibility that the problem occurs if the container height is larger that that of the content. In spite of that I had that occasional blank space.
So, for me, "contentSize" observer had a lot of flaws. I do not have a lot of experience with web technologies so I cannot answer what was the problem with this solution, but i saw that if I only print height in the console but do not do anything with it (eg. resize the constraints), it jumps to some number (e.g. 5000) and than goes to the number before that highest one (e.g. 2500 - which turns out to be the correct one). If I do set the height constraint to the height which I get from "contentSize" it sets itself to the highest number it gets and never gets resized to the correct one - which is, again, mentioned by @David Beck comment.
After lots of experiments I've managed to find a solution that works for me:
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
self.webView.evaluateJavaScript("document.readyState", completionHandler: { (complete, error) in
if complete != nil {
self.webView.evaluateJavaScript("document.body.scrollHeight", completionHandler: { (height, error) in
self.containerHeight.constant = height as! CGFloat
})
}
})
}
Of course, it is important to set the constraints correctly so that scrollView resizes according to the containerHeight constraint.
As it turns out didFinish navigation method never gets called when I wanted, but having set document.readyState
step, the next one (document.body.offsetHeight
) gets called at the right moment, returning me the right number for height.
WKWebView not staying flush with status bar
From what I have seen in the images you posed, you don't have any layout constraints for the WebView, which I think explains what you are seeing. Without those constrains, the view will not be resized to fit various devices. Below is what I would suggest for constraints if you want things "flush" to top and bottom bars (important to place the constraint against the SafeArea). To add these constraints drag the web view to the edges of the display until you see the a dotted blue line and then click the button that looks like a tie-fighter (second button from right) and then click the red dotted |---| symbols to apply constraints in each direction.
This should give you layouts that look like this:
When running in the simulator, you get the the results shown below. You can see things look a bit different on the iPhone X devices, but this how things are designed on those devices to make sure the controls are accessible. One thing I did notice was that the grey area you see in Xcode for the web view, does not correctly move when you change the orientation or size of the device in Xcode. However, the edges of the display do move correctly so I would chalk that up to a bug Xcode.
Really hope that helps. I remember being very confused when it came to constraints when I first started. It takes a bit to get your head around things.
iPhone 8
iPhone 8 landscape
iPad
iPad Landscape
iPhone X
iPhone XR
Related Topics
Swift - How to Save Memory Using Alamofireimage/Imageshack
How to Limit an iOS App Only to 4 Inch Screen Devices
Images Can't Contain Alpha Channels or Transparencies
iPhone Sdk:How to Play Video Inside a View? Rather Than Fullscreen
How to Change the Color of the Text in a Uipickerview Under iOS 7
Is iOS Carplay API Public? How to Integrate Carplay
iOS 11 Uitabbar Uitabbaritem Positioning Issue
Play Video in Background Using Avplayer
Class Is Implemented in Both. One of the Two Will Be Used
Dynamic Height for Static Table Cells with Wrapping Labels
Googlemaps Basic iOS Demo App Crash - Unrecognized Selector Sent to Instance
Center Nstextattachment Image Next to Single Line Uilabel
How to Dismiss Keyboard iOS Programmatically When Pressing Return
Dynamic Size Uicollectionview Cell
How to Enable Arc Project-Wide in Xcode 4.2
iOS 7 - How to Disable the Swipe Back and Forward Functionality in Safari