Search code examples
swiftuiios18scrollviewreader

ScrollViewReader not scrolling to list item on iOS 18


For a long list, I would like to scroll to a particular item when it appears. This works perfectly on iOS 17:

NavigationLink {
    ScrollViewReader { proxy in
        List {
            ForEach(sections, id: \.key) { section in
                SomeListItem(section: section)
                .id(section.key) // adding or removing this does not help.
            }
        }.onAppear {
            proxy.scrollTo(currentSection, anchor: .center)
        }
    }            
} label: {
    Image(systemName: "filemenu.and.selection").padding()
}.buttonStyle(DefaultButtonStyle())

However, it does nothing on iOS 18. Has anyone been able to get around this?


Solution

  • May I know what Xcode version and Device/Simulator version you're using for testing this out.

    Ran similar code in Xcode 16.0(16A242d) and iPhone XR iOS 18.0(22A3354) and it works just fine

    struct ContentView: View {
        var body: some View {
            ScrollViewReader { scrollView in
                Button("Jump to 50") {
                    scrollView.scrollTo(50, anchor: .center)
                }
                
                List {
                    ForEach(1...50, id: \.self) { row in
                        Text("Row \(row)")
                    }
                }
            }
        }
    }
    

    shows screen recording of iPhone XR of the implementation

    Edit 1 - Answer to edited question

    Embedding inside Navigation Link also works.

    struct ContentView: View {
        var body: some View {
            NavigationView {
                NavigationLink {
                    ScrollViewReader { scrollView in
                        List {
                            ForEach(1...1000, id: \.self) { row in
                                Text("Row \(row)")
                            }
                        }.onAppear {
                            scrollView.scrollTo(900, anchor: .center)
                        }
                    }
                } label: {
                    Image(systemName: "filemenu.and.selection").padding()
                }.buttonStyle(DefaultButtonStyle())
            }
        }
    } 
    

    enter image description here