Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Programmatically select item from list

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading