Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WKWebView incorrect content width in landscape with safe area

This is how it looks: wrong offsets and width Maximally simple code to reproduce:

#import "ViewController.h"
#import <WebKit/WebKit.h>

@implementation ViewController

- (void)loadView
{
    WKWebView* webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:[[WKWebViewConfiguration alloc] init]];
    self.view = webView;

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://apple.com"]]];
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscape;
}

@end

This happens only to the websites with viewport-fit=cover set. If you open same websites in Safari, you can see that first draw frame has the same problem, but it instantly resizes correctly after.

This happens only when launched in landscape. Rotation to portrait and back to landscape fixes this. Even minimizing app and opening it again fixes this.

So is there anything I can do from code to force it fix itself? I've already tried calling setNeedsLayout and layoutIfNeeded to whole WKWebView tree. Setting scroller insets will make content look like it doesn't have viewport-fit=cover set. This happens on iOS 12 and 13 (tested) and iOS 13 Simulator.

like image 580
KleMiX Avatar asked Nov 26 '25 03:11

KleMiX


1 Answers

It is not the perfect solution but I managed to fix this by adding the webView as subView to self.view and add constraints to superview instead of safeArea to get the same effect.

Solution:

  • Connect trailing constraint to a variable
  • Set constraint isEnabled to false in viewDidLoad (to optimize check for deviceOrientation)
  • In function webView(WKWebView, didFinish: WKNavigation) set constraint isEnabled to true
  • Don't forget to register to navigationDelegate of the webView

    @IBOutlet var mainWebView: WKWebView!
    @IBOutlet var trailingConstraint: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let orientation = UIDevice.current.orientation
        if orientation == .landscapeLeft || orientation == .landscapeRight {
            trailingConstraint.isActive = false
        }
    
        mainWebView.navigationDelegate = self
        mainWebView.load(URLRequest(url: URL(string: "https://apple.com")!))
    }
    
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        trailingConstraint.isActive = true
    }
    
like image 57
Stefan Avatar answered Nov 28 '25 16:11

Stefan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!