Make ScrollViewReader scroll to item using a list and identifiable protocol in SwiftUI

1.3k views Asked by At

I can't make ScrollViewReader to scroll on my List(). I have read many discussions such this or this

I use a model with Identifiable protocol and id as Int:

struct Country: Identifiable, Codable, Hashable {

        // database fields
        var id: Int64?
        var name: String
}

My view is currently like that:

            ScrollViewReader { proxy in
                    VStack {
                            Button(action: {
                                    proxy.scrollTo(38) // just a test
                            })
                            { Text("Jump to") }
                                 
                            List() {
                                    ForEach(countries) { country in

                                            Button (action: {
                                                    wine.countryId = country.id
                                                    // pop
                                                    self.mode.wrappedValue.dismiss()
                                            }) {
                                                    // cell content
                                                    HStack {
                                                            Image(country.flag).resizable().frame(width: 24.0, height: 24.0)
                                                            Text(country.name)
                                                    }
                                            }
                                            //.id(country.id)
                                       }
                                }
                        
                        }
                }
    }

I tried using an .id() to identify each row/button without success too. I don't know if I need id() as ForEach() use the identifiable protocol of the country to identify each item.

One important thing: countries are NOT displayed in the logical order (1,2,3...) of their var id. But even with the id(country.id) modifier, it never scroll to the right row/button of the list.

Most of examples we can find on the web use a simple index iteration for rows, and not a real model with struct().

1

There are 1 answers

2
Asperi On BEST ANSWER

Types of matched identifiers must be the same, so as your id is Optional then in scrollTo it should be optional as well, like

Button(action: {
   proxy.scrollTo(Optional(Int64(38))) // << here !!
})

Tested with your replicated snapshot on Xcode 13 / iOS 15