Reputation: 179
I am fairly new to iOS development and I'm using a WKWebView
to display a page that plays a video using the Vimeo Player. When the app starts up, it shows the view correctly, no matter what orientation it is currently in. However, once I change the orientation the view will either look zoomed in or has whitespace below the video.
The annoying thing about this is that it's not consistent. Sometimes the view displays correctly, sometimes it doesn't. If I try to zoom the view in or out or try to scroll when using the app it usually corrects itself, but even that does not seem to be 100% reliable.
Some screenshots (tested on iPad 2):
Landscape orientation (correct):
Portrait orientation (correct):
Landscape orientation (incorrect):
Portrait orientation (incorrect):
And the code used to produce this result:
import Foundation
import UIKit
import WebKit
class VideoViewController : UIViewController, WKScriptMessageHandler {
@IBOutlet var containerView : UIView! = nil
var webView: WKWebView?
override func loadView() {
super.loadView()
self.webView = WKWebView()
let contentController = WKUserContentController();
let scaleToFit = WKUserScript(source: "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width, initial-scale=1.0'); document.getElementsByTagName('head')[0].appendChild(meta);", injectionTime: WKUserScriptInjectionTime.AtDocumentStart, forMainFrameOnly: true)
contentController.addUserScript(scaleToFit)
contentController.addScriptMessageHandler(self, name: "callbackHandler")
self.view = webView!
}
override func viewDidLoad() {
super.viewDidLoad()
refreshUI()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func refreshUI() {
let url = NSURL(string: "https://photofactsacademy.nl/api/vp.asp?id=152839850")
let requestObj = NSURLRequest(URL: url!)
webView!.loadRequest(requestObj)
}
func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) {
if(message.name == "callbackHandler") {
print("JavaScript is sending a message \(message.body)")
}
}
}
I looked through SO for WKWebView and orientation change and didn't find anything that helped me.
Your help is appreciated.
Upvotes: 15
Views: 12340
Reputation: 3508
You don't need to reload the entire web page. You just need to reload its input views. Make sure you have set constraints to web view properly and then add below code while changing orientation.
// Reload inputs so that webview can adjust its content according to orientation
[self.webView reloadInputViews];
Upvotes: 2
Reputation: 2404
After few hours of struggling, this is what worked for me:
<header><meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, shrink-to-fit=no'></header><body style='margin: 0px; padding: 0px; width:100%; height:100%;'>...
Set width and height of both body and your video element to 100% and disable user scaling through header tag.
Upvotes: 1
Reputation: 7708
Can you try this
wkWebView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
Upvotes: 21
Reputation: 633
I was able to solve this problem by injecting a javascript reload call like this:
Swift:
func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animateAlongsideTransition(nil, completion: {
//Reset Frame of Webview
webView.evaluateJavaScript("location.reload();", completionHandler: nil)
}
Objective C:
-(void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
//Reset Frame of Webview
[_webView evaluateJavaScript:@"location.reload();" completionHandler:^(id _Nullable obj, NSError * _Nullable error) {
NSLog(@"error:%@", error);
}];
}
Upvotes: 5