tutorial support previous example broken before ios swift rotation addsubview wkwebview

ios - support - wkwebview navigation swift



WKWebView agregado como subvista no cambia de tamaño en rotación en Swift (4)

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

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

:)

Estoy trabajando para agregar una nueva vista de lectura a mi aplicación de navegador. Es otro controlador de vista, que solo incluye un WKWebView agregado como una subvista con un botón (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 controlador de vista principal con una transición realizada después de que el usuario toca un botón en el controlador de vista principal y esa URL se almacena como URL de página.

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

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 terminó de cargarse y funciona correctamente:

Esta es la vista después de rotar el dispositivo al paisaje:

Y esta es la ubicación de desplazamiento después de la rotación:

El uso de self.view = _webView hace que la vista cambie de tamaño correctamente, pero ignora todas las vistas en el Guión gráfico (ya que los contenidos de la Vista se están reescribiendo).

¿Cómo puedo solucionar este problema (sin reescribir self.view)?


Estoy publicando una respuesta para Objective-C, por si acaso alguien viene aquí buscándola

[self.webView setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];


versión rápida 3:

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


De hecho, como WKWebView solo se puede agregar mediante programación, tiene la máscara de aumento automático a la marca de restricciones activada de manera predeterminada (al agregar componentes y restricciones dentro de Interface Builder, generalmente está deshabilitada). Creo que la solución correcta sería:

webView?.translatesAutoresizingMaskIntoConstraints = false

después de agregar las restricciones / anclas.