What's the difference between the two possibilities? They both seem to work the same way.
struct ContentView: View {
@Environment(\.openURL) private
var openURL
let url = "https://google.com"
var body: some View {
VStack(spacing: 25) {
Button("Go to Google via openURL") {
openURL(URL(string: url) !)
}
Link(destination: URL(string: url) !, label: {
Text("Go to Google-Search via Link")
})
}
}
}
The openURL
environment value is something you can call from anywhere, whereas Link
is a View
that can only be triggered by a user. They are very different.
I will assume that you are asking about the difference between a Button
that calls openURL
and a Link
.
You can try dumping the body
of a Link
.
let link = Link(destination: URL(string: "https://google.com")!, label: {
Text("Go to Google-Search via Link")
})
let _ = dump(link.body)
On iOS 18.1, it shows that the body
is of this type:
SwiftUI._ConditionalContent<
SwiftUI.ModifiedContent<
SwiftUI.ModifiedContent<
SwiftUI.Button<SwiftUI.Text>,
SwiftUI.(unknown context at $1d30f33c8).IgnoreViewRespondersModifier
>,
SwiftUI.AccessibilityAttachmentModifier
>,
SwiftUI.ModifiedContent<
SwiftUI.Button<SwiftUI.Text>,
SwiftUI.AccessibilityAttachmentModifier
>
>
As you can see from the output, it's just a Button
modified with some accessibility modifier. It can be shown that the button's action calls openURL
at some point, by setting openURL
to something else using .environment
.
From the dump, it seems like the accessibility modifier likely is
.accessibilityAddTraits(.isLink)
in addition to an accessibility property containing the destination URL.
There is also the IgnoreViewRespondersModifier
which gets added conditionally in the true branch, but I have been unable to find a case where the true branch is executed.
As with everything that is undocumented, this may very well change in future versions.