Safari in SwiftUI
You started playing around with SwiftUI, and you want to present a Safari(WebView), you search in the documentation, and..., SwiftUI has no native way to display a WebView!
To use Safari (SFSafari) you need to create a custom UIViewControllerRepresentable
which is needed to use ViewControllers in SwiftUI.
This post contains, 3 sections,
- The code in steps
- The code (complete)
- Example on how to use.
Full source code of our UIViewControllerRepresentable
.
import SwiftUI
import SafariServices
import UIKit
/// Make a Safari View for SwiftUI
public struct SafariView: UIViewControllerRepresentable {
typealias UIViewControllerType = SFSafariViewController
/// Create a binding for our URL String
@Binding var urlString: String
/// Public initializer.
public init(url: String) {
_urlString = url
}
/// Make a UIViewController for SwiftUI.
public func makeUIViewController(
context: UIViewControllerRepresentableContext<SafariView>
) -> SFSafariViewController {
// Check if the url is valid, otherwise fatalError.
guard let url = URL(string: urlString) else {
fatalError("Invalid urlString: \(urlString)")
}
// Generate the SFSafariViewController.
let safariViewController = SFSafariViewController(url: url)
// Optional, set int/accentcolor.
safariViewController.preferredControlTintColor = UIColor(Color.accentColor)
// We want our view to have a close button instead of 'done'
safariViewController.dismissButtonStyle = .close
// Return the view
return safariViewController
}
public func updateUIViewController(
_ safariViewController: SFSafariViewController,
context: UIViewControllerRepresentableContext<SafariView>) {
return
}
}
How to use:
struct CodeView: View {
// whether or not to show the Safari ViewController
@State var showSafari = false
// initial URL string
@State var urlString = "https://wesleydegroot.nl"
var body: some View {
VStack {
Button("Open This article") {
self.urlString = "https://wesleydegroot.nl/blog/Safari-in-SwiftUI"
showSafari = true
}
}
.popover(isPresented: $showSafari, content: {
SafariView(urlString: $urlString)
})
}
}
// MARK: Preview
struct CodeView_Previews: PreviewProvider {
static var previews: some View {
CodeView()
.previewLayout(PreviewLayout.sizeThatFits)
.padding()
.previewDisplayName("Code Preview")
}
}
Read more
- Observable Geocoder • 3 minutes reading time.
- Safari in SwiftUI • 2 minutes reading time.
- Understanding assertions in Swift • 4 minutes reading time.
Share
Share Mastodon Twitter LinkedIn Facebook