SFSafariViewController in SwiftUI

If you would like to have a Safari web view in your SwiftUI app, you’ll probably want to create a UIViewControllerRepresentable for SFSafariViewController. You’ll see from the documentation that it can’t be built in as a sub-view. It basically needs to be on its own, so the natural place to put a Safari web view is in a sheet.

Well, if you do that, and you simply copy and paste one of the numerous examples, you’ll find when you scroll, the navigation bar can collapse and doesn’t look particularly nice. It looks like a bug.

What you need to do is set the configuration barCollapsingEnabled to false and ensure you do it before you create the SFSafariViewController object.

Here’s a full example that will work nicely in a SwiftUI sheet.

import SwiftUI
import SafariServices

struct SafariWebView: UIViewControllerRepresentable {
    typealias UIViewControllerType = SFSafariViewController

    let url: URL

    func makeUIViewController(context: Context) -> SFSafariViewController {
        let configuration = SFSafariViewController.Configuration()
        configuration.barCollapsingEnabled = false

        let controller = SFSafariViewController(url: url, configuration: configuration)
        return controller
    }

    func updateUIViewController(_ uiViewController: SFSafariViewController, context: Context) {

    }
}

// Example Usage:
.sheet(isPresented: $showPage) {
    SafariWebView(url: myStateObjectURL)
        .ignoresSafeArea()
}

I hope that helps.