Structure¶
Link¶
A button that opens a URL¶
Declaration¶
struct Link<Label> : View where Label : View
Overview¶
A Link opens a URL when the user clicks. There are three initializers:
For example:
struct ExampleView: View {
let urlString = "https://swiftontap.com"
var body: some View {
Group {
if let url = URL(string: urlString) {
// Creates a Link
Link("View SwiftOnTap", destination: url)
}
}
}
}

Creating a Link with a View¶
struct ExampleView: View {
let url: String = "https://swiftontap.com"
var body: some View {
Group {
if let url = URL(string: url) {
Link(destination: url) {
RoundedRectangle(cornerRadius: 10)
.fill(Color.pink)
.padding()
}
}
}
}
}

Background on Link in SwiftUI¶
Before Link was added to SwiftUI, there was no equivalent of a hyperlink outside of a WKWebView.
It was possible to create a button with blue text that opens a URL, but this requires the logic to be added manually each time. For example:
struct ContentView: View {
let urlString = "https://swiftontap.com"
var body: some View {
if URL(string: urlString) != nil {
//The old way to create a Link-style Button
Button("Read more") {
if let url = URL(string: urlString) {
UIApplication.shared.open(url, options: [:], completionHandler: {\_ in })
}
}
} else {
EmptyView()
.onAppear { assertionFailure("URL was nil") }
}
}
}
This example is held back by the lack of optional binding (if let or guard let) in the first version of SwiftUI, as it is instead restricted to comparing the URL to nil to ensure it exists. When this comparison confirms that the URL is not nil, this still doesn’t mean I can use it in the Button without unwrapping it first. This is why there is a slightly confusing additional step in the Button action, which optionally binds the URL to ensure that it is not nil.
The assertionFailure could have been in an else statement after the if let in the Button action, but the EmptyView has been added for consistency with the above Link example. An else statement containing EmptyView is not required, as any if statement around the only occupant of a ViewBuilder closure will return EmptyView when the if condition is false. If the URL was nil the user would see nothing, but an assertion would be triggered for the developer in debug mode.
This would allow us to be aware that the URL was nil, but without causing a crash for the end-user.
With updates to SwiftUI, the old code would roughly translate to the code below:
struct ExampleView: View {
let urlString = "https://swiftontap.com"
var body: some View {
Group {
if let url = URL(string: urlString) {
// The new way to create a Link
Link("View SwiftOnTap", destination: url)
}
}
}
}

Now that SwiftUI supports if let, it is possible to directly create properties like the URL and create Views that use that data. Just as before, the link is only shown when the URL can be created, but it is not necessary to do multiple checks just to make sure that this is the case.
Availability¶
iOS 14.0+
macOS 11.0+
tvOS 14.0+
watchOS 7.0+
Topics¶
Type Alias¶
Body The type of view representing the body of this view.
Instance Property¶
body The content and behavior of the view.
Initializer¶
init(_:destination:) A Link initializer that opens a link when a title conforming to StringProtocol is clicked.
init(_:destination:) A Link initializer that opens a link when text is clicked.
init(destination:label:) A Link initializer that opens a link when a view is clicked.