I want to load specific webpages inside a Safari browser INSIDE the app (i.e. not going outside the app), and it should exist within the same safari-environment, i.e. no regular webviews.
I have this SafariView
to enable that in SwiftUI.
Now I want to load different urls from the same scene (The number varies, can be 0 to 20-ish).
When I open the SafariViews though only the first url is opened. When I click the second button the first url is loaded again.
import SwiftUI
import SafariServices
struct ContentView: View {
@State private var showSafari = false
var body: some View {
VStack {
Button(action: {
showSafari = true
}) {
Text("Apple")
.padding()
}
.fullScreenCover(isPresented: $showSafari) {
SafariView(url: URL(string: "http://www.apple.com")!)
}
Button(action: {
showSafari = true
}) {
Text("Google")
.padding()
}
.fullScreenCover(isPresented: $showSafari) {
SafariView(url: URL(string: "http://www.google.com")!)
}
}
}
}
struct SafariView: UIViewControllerRepresentable {
var url: URL
func makeUIViewController(
context: UIViewControllerRepresentableContext<SafariView>
) -> SFSafariViewController {
return SFSafariViewController(url: url)
}
func updateUIViewController(
_ uiViewController: SFSafariViewController,
context: UIViewControllerRepresentableContext<SafariView>
) {}
}
What I am doing in another scene is creating 2 separate showSafari
variables, there it seems to work, but in that case it is only ever 2 hard-coded urls being shown.
Is there something I am missing in this safari-implementation, or do I possibly need to work around this by creating an array of showSafari
booleans?
Try using .fullScreenCover(item:content:)
:
struct ContentView: View {
@State private var safariURL: String?
var body: some View {
VStack {
Button(action: {
safariURL = "http://www.apple.com"
}) {
Text("Apple")
.padding()
}
Button(action: {
safariURL = "http://www.google.com"
}) {
Text("Google")
.padding()
}
}
.fullScreenCover(item: $safariURL) {
if let url = URL(string: $0) {
SafariView(url: url)
}
}
}
}
Note that you need to pass some Identifiable
variable in item
. A possible solution is to conform String to Identifiable
:
extension String: Identifiable {
public var id: Self { self }
}