Reputation: 332
This is how it looks:
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.
Upvotes: 3
Views: 2331
Reputation: 959
I ran into this same issue but I believe I found a simpler solution that doesn't involve deactivating and reactivating constraints.
Instead, call setNeedsLayout()
from the didFinish
navigation delegate method. This triggers another layout pass after the web view has finished loading:
override func viewDidLoad() {
super.viewDidLoad()
mainWebView.navigationDelegate = self
mainWebView.load(URLRequest(url: URL(string: "https://apple.com")!))
}
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.setNeedsLayout()
}
To ensure you're reliably reproducing the issue, you can slow the simulator animation to ensure the web view loads before the view controller finishes animating on screen.
Thank you @Stefan for pointing me in the right direction!
Upvotes: 0
Reputation: 1471
Hi, You need to change viewport.
Please change your "loadView" function with below code.
- (void)loadView
{
NSString *jScript = @"var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);";
WKUserScript *wkUScript = [[WKUserScript alloc] initWithSource:jScript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *wkUController = [[WKUserContentController alloc] init];
[wkUController addUserScript:wkUScript];
WKWebViewConfiguration *wkWebConfig = [[WKWebViewConfiguration alloc] init];
wkWebConfig.userContentController = wkUController;
WKWebView* webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:wkWebConfig];
webView.insetsLayoutMarginsFromSafeArea = false;
webView.scrollView.insetsLayoutMarginsFromSafeArea = false;
webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
webView.translatesAutoresizingMaskIntoConstraints = NO;
self.view = webView;
UIWindow *window = UIApplication.sharedApplication.windows.firstObject;
CGFloat topPadding = window.safeAreaInsets.top;
CGFloat bottomPadding = window.safeAreaInsets.bottom;
CGFloat leftPadding = window.safeAreaInsets.left;
CGFloat rightPadding = window.safeAreaInsets.right;
self.additionalSafeAreaInsets = UIEdgeInsetsMake(-topPadding, -leftPadding, -bottomPadding, -rightPadding);
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"https://apple.com"]]];
}
Upvotes: 0
Reputation: 166
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:
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
}
Upvotes: 2