So I have this minimum repro code:
struct ListViewWithNewAPI: View {
@State var selectedString: String? = nil
var body: some View {
let details = ["foo", "bar", "baz"]
NavigationStack {
List {
ForEach(details, id: .self) { detail in
NavigationLink(detail, value: detail)
}
}
.navigationDestination(item: $selectedString) { detail in
Text("This is a detailed page for (detail)")
.navigationTitle("Detail page")
}
.navigationTitle("List page")
}
}
}
When I tap on the link, I got a warning:
A NavigationLink is presenting a value of type “String” but there is no matching navigationDestination declaration visible from the location of the link. The link cannot be activated.
But as you can tell, I did provide the navigationDestination
with correct String type. What is going on here?
Edit: This is my old way of writing it:
List {
ForEach(details, id: .self) { detail in
let destination = Text("This is a detailed page for (detail)")
.navigationTitle("Detail page")
NavigationLink(
detail,
destination: destination,
tag: detail,
selection: $selectedString)
}
}
This API has been deprecated, but it was working well – I did not have to manually set $selectedString
.
2
Answers
You are really close here. The
navigationDestination
you should be using is thefor
variation that allows you to associate it with a type instead of a selected value:I think you are mixing the different ways of using
.navigationDestination
.You can either do it like this:
or… you can leave the
.navigationDestination
like you have it and change the links to something that updates the state variableselectedString
, like this:EDIT This works too and gives you the right arrow like before. It’s a slightly different way of building the
List
: