WKWebView not showing Navigation Bar

Viewed 1693

I have a view in SwiftUI that shows a WKWebView which is passed to the main ContentView using the UIViewControllerRepresentable class, implemented following the instructions from Paul Huson's 'Creating a simple browser with WKWebView. However, when I load the app in the simulator, there doesn't seem to be a Navigation Bar.

Here is my code:

The ContentView and BrowserView

struct ContentView: View {

    let browserView = BrowserView()
    var body: some View {
        browserView
    }
}

struct BrowserView: UIViewControllerRepresentable {

    func makeUIViewController(context: UIViewControllerRepresentableContext<BrowserView>) -> WKBrowser {
        let browser = WKBrowser()
        return browser
    }

    func updateUIViewController(_ uiViewController: WKBrowser, context: UIViewControllerRepresentableContext<BrowserView>) {
        // Empty
    }

}

The WKBrowser class

class WKBrowser: UIViewController, WKNavigationDelegate {

    var webView: WKWebView!

    var webURL = URL(string: "https://www.hackingwithswift.com")!

    override func loadView() {
        webView = WKWebView()
        webView?.navigationDelegate = self
        self.view = webView
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        webView.load(URLRequest(url: webURL))
    }
}

The result:

The WKWebView

Compared to the WKWebView from the tutorial which has the Navigation Bar and looks like this:

enter image description here

What do I have to add or edit in order to ensure the Navigation Bar appears?

Edit 05/19/2020:

I'd like to add items to the navigation bar via the navigationItem.rightBarItem function, added to the viewDidLoad, like so:

override func viewDidLoad() {
    super.viewDidLoad()
    webView.load(URLRequest(url: webURL))
    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Open", style: .plain, target: self, action: #selector(someFunction)
}

@objc func someFunction(){
    // Do something
}

Optimally, the result would look something similar to SFSafariViewController:

enter image description here

But when when I wrap the UIViewRepresentable class in a NavigationView, these items are not added to the Navigation Bar that appears, and I instead get this:

enter image description here

3 Answers

If you want to work with navigation bar in UIKit part then you need to wrap your UIKit browser in UINavigationController, like below

Tested with Xcode 11.4 / iOS 13.4

demo

struct BrowserView: UIViewControllerRepresentable {

    func makeUIViewController(context: Context) -> UINavigationController {
        let browser = WKBrowser()
        return UINavigationController(rootViewController: browser)
    }

    func updateUIViewController(_ uiViewController: UINavigationController, context: Context) {
        // Empty
    }

}

actually you have a simpler way.

first wrap a web view:

struct WebView: UIViewRepresentable {
    var url: URL
    
    func makeUIView(context: Context) -> WKWebView {
        return WKWebView()
    }

    func updateUIView(_ webView: WKWebView, context: Context) {
        let request = URLRequest(url: url)
        webView.load(request)
    }
}

then you can put the WebView into a VStack and this will make the UIView stuff like a SwiftUI component. and everything work fine!

   var body: some View {
        NavigationView {
            VStack {
                WebView(url: someURL)
            }
            .toolbar {
               // buttons here ....
            }
        }
   }

Great!

I'm using Xcode 14 while following the same tutorial. Embedding in Navigation Controller solved the problem without changing any of the code from the tutorial.

Related