WKWebView agregado como Subview no cambia de tamaño en rotation en Swift

Estoy trabajando para agregar una nueva vista de lectura a mi aplicación de browser. Es otro controller de vista, que solo incluye una WKWebView agregada como una subvista con un button (y un gesto) para cerrar la vista. Todo funciona muy bien, pero cuando giro el dispositivo, la subvista no cambia de tamaño, por lo que tengo la mitad de la pantalla vacía.

El WKWebView en la vista de lectura obtiene la URL del controller de vista principal con un segue realizado después de que el usuario toca un button en el controller de vista principal y esa URL se almacena como URL de página web.

Aquí está el código que usé:

import UIKit import WebKit class ReadingViewController: UIViewController, UIGestureRecognizerDelegate, WKNavigationDelegate, WKScriptMessageHandler { @IBOutlet weak var _closeButton: UIButton! @IBOutlet weak var _progressView: UIProgressView! @IBOutlet weak var _loadingErrorView: UIView! var webpageURL: NSURL? var _webView: WKWebView? var _isMainFrameNavigationAction: Bool? var _loadingTimer: NSTimer? var _swipeFromTopRecognizer: UIScreenEdgePanGestureRecognizer? var _panFromRightRecognizer: UIScreenEdgePanGestureRecognizer? var _panFromLeftRecognizer: UIScreenEdgePanGestureRecognizer? var _errorView: UIView? var _isCurrentPageLoaded = false var _progressTimer: NSTimer? var _isWebViewLoading = false override func viewDidLoad() { super.viewDidLoad() var contentController = WKUserContentController(); var scaleToFit = WKUserScript(source: "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta);", injectionTime: WKUserScriptInjectionTime.AtDocumentStart, forMainFrameOnly: true) contentController.addUserScript(scaleToFit) contentController.addScriptMessageHandler(self, name: "callbackHandler") var webViewConfiguration: WKWebViewConfiguration = WKWebViewConfiguration() webViewConfiguration.allowsInlineMediaPlayback = true webViewConfiguration.mediaPlaybackRequiresUserAction = false _webView = WKWebView(frame: self.view.frame, configuration: webViewConfiguration) self.view.addSubview(_webView!) _webView!.navigationDelegate = self self.view.sendSubviewToBack(_webView!) _webView!.allowsBackForwardNavigationGestures = true _loadingErrorView.hidden = true _swipeFromTopRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: Selector("handleSwipeFromTop:")) _swipeFromTopRecognizer!.edges = UIRectEdge.Top _swipeFromTopRecognizer!.delegate = self self.view.addGestureRecognizer(_swipeFromTopRecognizer!) _progressView.hidden = true var urlAsString = "\(webpageURL!)" loadURL(urlAsString) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // UI Control Functions func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true } @IBAction func closeReadingView(sender: AnyObject) { self.dismissViewControllerAnimated(true, completion: nil) } func closeButtonEnabled(bool:Bool) { _closeButton.enabled = bool } func userContentController(userContentController: WKUserContentController, didReceiveScriptMessage message: WKScriptMessage) { if(message.name == "callbackHandler") { println("JavaScript is sending a message \(message.body)") } } // WebView Functions func webView(webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { _loadingErrorView.hidden = true _isWebViewLoading = true _progressView.hidden = false _progressView.progress = 0 _progressTimer = NSTimer.scheduledTimerWithTimeInterval(0.01667, target: self, selector: "progressTimerCallback", userInfo: nil, repeats: true) _loadingTimer = NSTimer.scheduledTimerWithTimeInterval(30, target: self, selector: "loadingTimeoutCallback", userInfo: nil, repeats: false) } func loadingTimeoutCallback() { _webView?.stopLoading() handleWebViewError() } func webView(webView: WKWebView, didCommitNavigation navigation: WKNavigation!) { _isCurrentPageLoaded = true _loadingTimer!.invalidate() _isWebViewLoading = false if self._webView!.URL == webpageURL! { handleWebViewError() println(webpageURL!) println(self._webView!.URL!) } else { println("Page was loaded successfully") println(webpageURL!) println(self._webView!.URL!) } } func webView(webView: WKWebView, didFinishNavigation navigation: WKNavigation!) { _isCurrentPageLoaded = true _loadingTimer!.invalidate() _isWebViewLoading = false } func webView(webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) { if let newFrameLoading = _isMainFrameNavigationAction { } else { handleWebViewError() } } func webView(webView: WKWebView, didFailNavigation navigation: WKNavigation!, withError error: NSError) { if let newFrameLoading = _isMainFrameNavigationAction { } else { handleWebViewError() } } func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void) { if (navigationAction.targetFrame == nil && navigationAction.navigationType == .LinkActivated) { _webView!.loadRequest(navigationAction.request) } _isMainFrameNavigationAction = navigationAction.targetFrame?.mainFrame decisionHandler(.Allow) } func handleWebViewError() { _loadingTimer!.invalidate() _isCurrentPageLoaded = false _isWebViewLoading = false displayLoadingErrorMessage() } func progressTimerCallback() { if (!_isWebViewLoading) { if (_progressView.progress >= 1) { _progressView.hidden = true _progressTimer?.invalidate() } else { _progressView.progress += 0.2 } } else { _progressView.progress += 0.003 if (_progressView.progress >= 0.95) { _progressView.progress = 0.95 } } } func loadURL(urlString: String) { let addrStr = httpifyString(urlString) let readingAddr = addrStr.stringByAddingPercentEncodingForFormUrlencoded()! let addr = NSURL(string: "http://mobilizer.instapaper.com/m?u=\(readingAddr)") if let webAddr = addr { let req = NSURLRequest(URL: webAddr) _webView!.loadRequest(req) } else { displayLoadingErrorMessage() } } func httpifyString(str: String) -> String { let lcStr:String = (str as NSString).lowercaseString if (count(lcStr) >= 7) { if (lcStr.rangeOfString("http://") != nil) { return str } else if (lcStr.rangeOfString("https://") != nil) { return str } } return "http://"+str } func displayLoadingErrorMessage() { _loadingErrorView.hidden = false } func handleGoBackPan(sender: UIScreenEdgePanGestureRecognizer) { if (sender.state == .Ended) { _webView!.goBack() } } func handleGoForwardPan(sender: AnyObject) { if (sender.state == .Ended) { _webView!.goForward() } } func handleSwipeFromTop(sender: AnyObject) { self.dismissViewControllerAnimated(true, completion: nil) } override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { coordinator.animateAlongsideTransition({ context in self._webView!.frame = CGRectMake(0, 0, size.width, size.height) }, completion: nil) } 

}

Y aquí hay algunas capturas de pantalla para demostrar el problema: esta es la vista después de que se terminó de cargar, funcionando correctamente: Así es como la vista se carga, funciona correctamente

Esta es la vista después de girar el dispositivo al paisaje: Esta es la vista después de la rotación

Y esta es la location de desplazamiento después de la rotation: Desplácese por la ubicación después de la rotación

Usar self.view = _webView hace que el tamaño de la vista sea correcto, pero ignora todas las vistas en el Storyboard (ya que los contenidos de la Vista se están reescribiendo).

¿Cómo puedo solucionar este problema (sin volver a escribir self.view)?

Logré resolver el problema usando esta línea de código:

 self._webView!.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight 

🙂

Versión rápida 3:

webView?.autoresizingMask = [.flexibleWidth, .flexibleHeight]

Estoy publicando una respuesta para Objective-C, por si acaso alguien viene a searchla

 [self.webView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth]; 

De hecho, como WKWebView solo se puede agregar mediante progtwigción, es posible que el marcador de máscara de autorizaciόn esté habilitado de forma pnetworkingeterminada (cuando se agregan componentes y restricciones dentro de Interface Builder, generalmente se lo inhabilita). Creo que la solución correcta sería:

 webView?.translatesAutoresizingMaskIntoConstraints = false 

después de agregar las restricciones / anclajes.