make WKWebview "real" fullscreen on iPhone X (remove safe area from WKWebView

27,760

Solution 1

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)
    }
}

Solution 2

Here is one more solution without overriding and executing javascript:

webView.scrollView.contentInsetAdjustmentBehavior = .never

In my case, it worked great.

Objective-c version:

[webView.scrollView setContentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentNever];

Solution 3

You can also extend safeAreaInsets from WKWebView.

extension WKWebView {
    override open var safeAreaInsets: UIEdgeInsets {
        return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
    }
}

Solution 4

Use AutoLayout constraints instead:

NSLayoutConstraint.activate([
    webView.topAnchor.constraint(equalTo: view.topAnchor),
    webView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
    webView.leftAnchor.constraint(equalTo: view.leftAnchor),
    webView.rightAnchor.constraint(equalTo: view.rightAnchor)
])

Remember to add viewport-fit=cover to your webpage's viewport meta tag, and use Safari's new variables to add padding to your content, to make sure that it respects the safe areas.

/* iOS 11 */
constant(safe-area-inset-*);
/* iOS 11.2 */
env(safe-area-inset-*);

Edit

I was also exploring options for adding the meta tag without doing any changes on the actual webpage. If I remember correctly I did succeed in adding the meta tag through Swift with the following piece of code:

webView.evaluateJavascript("document.querySelector('meta[name=viewport]').content = document.querySelector('meta[name=viewport]').content + ', viewport-fit=cover'", completionHandler: nil)

This is for use in a WKWebView by the way, and you'll need to execute it after the webpage has loaded obviously. Also some error handling should probably be done, as this will throw an exception if a metatag named viewport is missing, and the content will be , viewport-fit=cover if the content is empty to begin with.

Solution 5

just add a meta element in your webpage head "viewport-fit=cover"

like this:

meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,viewport-fit=cover"
Share:
27,760

Related videos on Youtube

j0h4nn3s
Author by

j0h4nn3s

I'm a applied computer science student and I will finish my studies this year with a Bachelor of Science.

Updated on July 09, 2022

Comments

  • j0h4nn3s
    j0h4nn3s almost 2 years

    I'm trying to implement a "real" fullscreen in App WebView, meaning I want the webcontent to fully go under the notch no matter what.

    This is the current situation I am facing, when framing the WebView to the superviews bounds: wkwebview on iPhone X The red border is the border of the webView (Also the size of the screen). Twitter has 100% height and width on the body.

    I understand that websites can't have 100% width in Safari and that its the default behaviour for the in App Browser to respect the safearea but especially in my case, where the webpages are somewhat designed for the app, I need to use the full space.

    I couldn't figure out how to set the webview to give its content the full size. Is there a way to change the safearea?

    Code Snippet:

    private var webView : WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        self.webView = WKWebView(frame: .zero)
    
        self.webView.layer.borderColor = UIColor.red.cgColor
        self.webView.layer.borderWidth = 2
    
        self.webView.load(URLRequest(url: URL(string: "https://www.twitter.com")!))
    
        self.view.addSubview(self.webView)
    }
    
    override func viewDidLayoutSubviews() {
        self.webView.frame = self.view.bounds
    }
    
    • matt
      matt over 6 years
    • matt
      matt over 6 years
      Also probably duplicate of stackoverflow.com/questions/46232812/…
    • j0h4nn3s
      j0h4nn3s over 6 years
      I am trying to find a solution where I don't need to change the websites HTML
    • matt
      matt over 6 years
      I understand, but the point is that Stack Overflow is aware of the problem and your asking the question again adds nothing to the mix. If it hasn't been solved already, it isn't going to be solved now because you ask again. If you think you have a legitimate use case and that Apple is doing the wrong thing, I strongly recommend filing a bug report.
    • Vinodh
      Vinodh over 6 years
  • j0h4nn3s
    j0h4nn3s over 6 years
    setting the constraint of the webview or the WKWebView doesn't help. It doesn't change anything, when it is already fullscreen. Adding ´viewport-fit=cover´ works, but as stated above, I am looking for a solution in swift without chaning the webpage
  • j0h4nn3s
    j0h4nn3s over 6 years
    I can see this work, but I still like my approach better in my use case.
  • fishinear
    fishinear over 6 years
    This is undefined behaviour. You should really not override existing methods in extensions. See e.g. this answer.
  • quemeful
    quemeful over 6 years
    it's weird that there are no compiler warnings if this is something that cannot be done (according to your link there)
  • Dimitris
    Dimitris over 6 years
    You can also just return zero insets
  • Abhi Beckert
    Abhi Beckert about 6 years
    @quemeful it can be done as long as you only do it once. If you do it twice, then it's undefined which one will apply. Also without seeing the source code for the parent class's method it's impossible to know if you are missing something important. These two reasons are why it shouldn't be done, even though it does technically work.
  • Gema Megantara
    Gema Megantara over 5 years
    Thank you, this made my day!
  • Austin
    Austin over 5 years
    You can also just add an extension for the webview on the view controller you want the webview to go into the safe zone: extension WKWebView{ override open var safeAreaInsets: UIEdgeInsets { return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) } }
  • Leon
    Leon over 3 years
    This is the correct way to turn safe area insets on and off.