添加为子视图的WKWebView在Swift中没有调整旋转大小 [英] WKWebView added as Subview is not resized on rotation in Swift

查看:160
本文介绍了添加为子视图的WKWebView在Swift中没有调整旋转大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在努力为我的浏览器应用添加新的阅读视图。它是另一个视图控制器,它只包含一个WKWebView作为子视图添加了一个按钮(和手势)来关闭视图。一切都很好,但是当我旋转设备时,子视图没有调整大小,所以我将屏幕的一半空了。

I'm working on adding a new reading view to my browser app. It is another view controller, that only includes a WKWebView added as a subview with a button (and gesture) to close the view. Everything works great, but when I rotate the device, the subview isn't resized, so I have one half of the screen empty.

阅读视图中的WKWebView获取用户点击主View Controller上的按钮后执行带有segue的主View Controller的URL,该URL存储为webpageURL。

The WKWebView in the Reading View gets the URL of the main View Controller with a segue performed after the user taps a button on the main View Controller and that URL is stored as webpageURL.

这是代码I used:

Here is the code I used:

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)
}

}

这里有一些屏幕截图来演示这个问题:
这是完成加载后的视图,工作正常:

And here are some screenshots to demonstrate the issue: This is the view after it finished loading, working correctly:

这是将设备旋转到横向后的视图:

This is the view after rotating the device to landscape:

这是之后的滚动位置轮换:

And this is the scroll location after rotation:

使用self.view = _webView可以正确调整视图大小,但忽略Storyboard上的所有视图(因为正在重写View的内容)。

Using self.view = _webView makes the view resize correctly, but ignores all the views on the Storyboard (since the View's contents are being rewritten).

如何修复此问题(不重写self.view)?

How can I fix this issue (without rewriting self.view)?

推荐答案

我设法通过使用以下代码来解决问题:

I managed to solve the problem by using this line of code:

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

:)

这篇关于添加为子视图的WKWebView在Swift中没有调整旋转大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆