I have a list with NavigationLinks in it. I wish to programmatically select/tap an item from the list. I tried using NavigationLink(tag…, selection…) API, but looks like it’s deprecated from iOS 16.
Code:
import SwiftUI
import Foundation
struct BookItem {
let id: Int
let name: String
init(id: Int, name: String) {
self.id = id
self.name = name
}
}
struct ContentView: View {
let bookList: [BookItem] = [BookItem.init(id: 0, name: "History"), BookItem.init(id: 1, name: "Math"), BookItem.init(id: 2, name: "Science")]
let selectBookItemId: Int = 1
var body: some View {
NavigationStack {
VStack {
List(bookList, id: \.name) { bookItem in
NavigationLink(destination: { DetailsView(bookItem: bookItem) },
label: {
HStack {
Text(bookItem.name)
Spacer()
}
.contentShape(Rectangle())
})
// NOTE: Was going to use this, but it is deprecated
// NavigationLink(
// destination: ,
// tag:,
// selection:,
// label: {})
}
}
}
}
}
struct DetailsView: View {
var bookItem: BookItem
var body: some View {
VStack {
Text(bookItem.name).font(.body.bold()).foregroundColor(Color.blue)
}
}
}
In my sample code above, let’s say I wish to programmatically select 2nd item from the list i.e. when I execute the code, it should show me DetailsView with "Math" written on it.
How can it be achieved now since NavigationLink API is deprecated?
Thanks!
>Solution :
An alternative way is to use NavigationPath. You could try this:
@State private var path = NavigationPath()
let selectBookItemId: Int
NavigationStack(path: $path) {
VStack {
List(bookList, id: \.name) { bookItem in
Button {
path.append(bookItem)
} label: {
HStack {
Text(bookItem.name)
Spacer()
}
.contentShape(Rectangle())
}
}
}
.navigationDestination(for: BookItem.self, destination: { book in
DetailsView(bookItem: book)
})
.onAppear { //<- here
if let book = bookList.first(where: {$0.id == selectBookItemId}) {
path.append(book)
}
}
}
And the BookItem must conform Hashable
struct BookItem: Hashable {
...
}
And passing id in such as:
ContentView(selectBookItemId: 1)