【问题标题】:How to add a navigation bar to WKWebView?如何向 WKWebView 添加导航栏?
【发布时间】:2015-02-18 22:02:30
【问题描述】:

我正在尝试使用 WKWebView 实现嵌入式 webView。我有初始配置,并且可以使用以下代码将网页加载到我的故事板中。

import UIKit
import WebKit

class WebViewViewController: UIViewController {
    @IBOutlet var containerView: UIView!
    var webView: WKWebView?

    override func loadView() {
        super.loadView()

        self.webView = WKWebView()
        self.view = self.webView!
    }


    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        var url = NSURL(string:"http://www.google.com/")
        var req = NSURLRequest(URL:url!)
        self.webView!.loadRequest(req)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


/*
// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.
}
*/

}

这样,我可以在我的应用程序中看到网页内容,但没有导航栏,我需要允许用户输入所需的 url。如何像任何其他网络浏览器一样添加导航栏?

【问题讨论】:

    标签: swift navigationbar wkwebview


    【解决方案1】:

    基于 Devran Cosmo 建议的网络 link,这是我的最终视图控制器代码。

    import UIKit
    import WebKit
    
    class WebViewViewController: UIViewController, UITextFieldDelegate, WKNavigationDelegate {
    
        var webView: WKWebView
        @IBOutlet weak var barView: UIView!
        @IBOutlet weak var urlField: UITextField!
    
        // Web Browser navigator
        @IBOutlet weak var backButton: UIBarButtonItem!
        @IBOutlet weak var forwardButton: UIBarButtonItem!
        @IBOutlet weak var reloadButton: UIBarButtonItem!
        @IBOutlet weak var progressView: UIProgressView!
    
        @IBAction func back(sender: UIBarButtonItem) {
            if (self.webView.canGoBack) {
                self.webView.goBack()
            }
        }
    
        @IBAction func forward(sender: UIBarButtonItem) {
            if (self.webView.canGoForward) {
                self.webView.goForward()
            }
        }
    
        required init(coder aDecoder: NSCoder) {
            self.webView = WKWebView(frame: CGRectZero)
            super.init(coder: aDecoder)
            self.webView.navigationDelegate = self
          }
    
        override func viewWillTransitionToSize(size: CGSize,  withTransitionCoordinator coordinator:     UIViewControllerTransitionCoordinator) {
            barView.frame = CGRect(x:0, y: 0, width: size.width, height: 30)
        }
    
        // Load user requested url
        func textFieldShouldReturn(textField: UITextField) -> Bool {
            urlField.resignFirstResponder()
            webView.loadRequest(NSURLRequest(URL: NSURL(string: urlField.text)!))
            var list : WKBackForwardList = self.webView.backForwardList
    
            println("BACK LIST")
            println(list.backList)
    
            return false
        }
    
        override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context:   UnsafeMutablePointer<()>) {
            if (keyPath == "loading") {
                backButton.enabled = webView.canGoBack
                forwardButton.enabled = webView.canGoForward
            }
    
            if (keyPath == "estimatedProgress") {
                progressView.hidden = webView.estimatedProgress == 1
                progressView.setProgress(Float(webView.estimatedProgress),  animated: true)
            }
        }
    
        func webView(webView: WKWebView!, didFinishNavigation navigation: WKNavigation!) {
            progressView.setProgress(0.0, animated: false)
        }
    
        func webView(webView: WKWebView!, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError!) {
            let alert = UIAlertController(title: "Error", message:  error.localizedDescription, preferredStyle: .Alert)
            alert.addAction(UIAlertAction(title: "Ok", style: .Default,  handler: nil))
            presentViewController(alert, animated: true, completion: nil)
        }
    
        override func viewDidLoad() {
            super.viewDidLoad()
            barView.frame = CGRect(x:0, y: 0, width: view.frame.width, height: 30)
    
            // Do any additional setup after loading the view.
            view.insertSubview(webView, belowSubview: progressView)
    
            webView.setTranslatesAutoresizingMaskIntoConstraints(false)
            let height = NSLayoutConstraint(item: webView, attribute: .Height, relatedBy: .Equal, toItem: view, attribute: .Height, multiplier: 1, constant: -44)
            let width = NSLayoutConstraint(item: webView, attribute:    .Width, relatedBy: .Equal, toItem: view, attribute: .Width, multiplier: 1,    constant: 0)
            view.addConstraints([height, width])
    
            // Disable navigation buttons on first loads
            backButton.enabled = false
            forwardButton.enabled = false
    
            webView.addObserver(self, forKeyPath: "loading", options: .New, context: nil)
            webView.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil)
    
            let url = NSURL(string:"http://www.appcoda.com")
            let request = NSURLRequest(URL:url!)
            webView.loadRequest(request)
        }
    }
    

    【讨论】:

    • 您的主故事板是如何设置的?我尝试使用此代码,但它只是白页。
    • WKWebView 是以编程方式添加的,因此对于初学者,我建议您只需在情节提要中添加一个普通视图,然后将 wkwebview 实例作为子视图添加到您在情节提要中添加的视图中。但是对于更优化的方式,您可以使用 wkwebview 的带有框架功能的 init 并手动输入 x,y,width 和 height 参数。
    • @Mike Purcell 可能您需要在 info.plist 中允许任意加载
    • 您现在可以使用 [NSAllowsArbitraryLoadsInWebContent] (developer.apple.com/library/archive/documentation/General/…),而不是允许对所有请求进行任意加载
    【解决方案2】:

    您必须将 WebViewViewController 包裹在 UINavigationController 中。并在导航栏中添加您需要的元素(后退按钮、刷新、位置文本字段)。

    看起来像这样:

    UINavigationController(rootViewController: WebViewViewController())
    

    示例(将此代码放入您的 AppDelegate):

    self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
    self.window?.rootViewController = UINavigationController(rootViewController: WebViewViewController())
    self.window?.makeKeyAndVisible()
    

    还有一个关于如何在 AppCoda 上使用 Webkit 创建 iOS 浏览器的教程。

    教程: http://www.appcoda.com/webkit-framework-intro/

    在那个页面,请看JFM的评论——教程的作者犯了一些错误:)

    【讨论】:

    • 谢谢你,我昨晚休息了一下,找到了本教程,并且工作完美......我将把我的最终代码粘贴到 JFM 的评论意见中:)......
    • 如果 WebViewController 不是 root 怎么办?
    【解决方案3】:
    override func viewDidLoad() {
        super.viewDidLoad()
        let screenSize: CGRect = UIScreen.main.bounds
        let myView = UIView(frame: CGRect(x: 0, y: 72, width: screenSize.width, height: screenSize.height-72))
        self.view.addSubview(myView)
        let preferences = WKPreferences()
        preferences.javaScriptEnabled = true
        let configuration  = WKWebViewConfiguration()
        configuration.preferences = preferences
        webview = WKWebView(frame : myView.frame , configuration : configuration)
        webview.navigationDelegate = self
        view.addSubview(webview)
        webview.load(URLRequest(url : URL (string: url!)!))
        webview.allowsBackForwardNavigationGestures = true
    }
    

    我设计了 72 px 导航栏和 WKWebView 设置点 (x:0,y:72),WkWebView 框架是 myView 边界

    【讨论】:

    • 为了帮助未来的开发者……在刘海屏手机(iPhone X、XS、……)上使用固定的 y 偏移量是错误的,您需要使用 view.safeAreaInsets.top 来考虑刘海屏。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2021-04-09
    • 1970-01-01
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多