mahan
mahan

Reputation: 14925

ScrollViewReader's scrollTo does not scroll

I have a simple SwiftUI list that I want to scroll to a row when a user click on a button. I have copied this code from hackingwithswift. It suppose to work, but it does not do.

struct ContentView: View {
    var body: some View {
        ScrollViewReader { proxy in
            VStack {
                Button("Jump to #50") {
                    proxy.scrollTo(5, anchor: .top)
                }

                List(0..<100) { i in
                    Text("Example \(i)")
                    .id(i)
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I tested it on iOS 14.2 both on simulator and a physical device.

I read its documentation, but there is not much info. So how to scroll to a row, for example, row 50?

Upvotes: 16

Views: 17320

Answers (3)

mahan
mahan

Reputation: 14925

ScrollViewReader works only with either:

  • Explicit use of ScrollView
  • List of identifiable collection

It does not work with List of Range<Int> unless you set its id explicitly.

Set id explicitly.

// List(0..<100, id: \.self)

struct ContentView: View {
    var body: some View {
        ScrollViewReader { proxy in
            VStack {
                Button("Jump to #50") {
                    proxy.scrollTo(50, anchor: .top)
                }

                List(0..<100, id: \.self) { i in
                    Text("Example \(i)")
                    .id(i)
                }
            }
        }
    }
}

// ForEach(0..<50000, id: \.self)

struct ContentView: View {
    var body: some View {
        ScrollView {
            ScrollViewReader { proxy in
                LazyVStack {
                    ForEach(0..<50000, id: \.self) { i in
                        Button("Jump to \(i+500)") {
                            proxy.scrollTo(i+500, anchor: .top)
                        }
                        Text("Example \(i)")
                            .id(i)
                    }
                }
            }
        }
    }
}

Upvotes: 39

Zin Win Htet
Zin Win Htet

Reputation: 2565

To use ScrollViewReader, only loop that uses indices and id as \.self will work.

eg. with List

ScrollViewReader { proxy in
      List(yourArray.indices, id: \.self) { index in
            // your item
      }
}

eg. with ScrollView

ScrollViewReader { proxy in
      ScrollView { 
         ForEach(yourArray.indices, id: \.self) { index in 
              // your item
         }
      }
}

Upvotes: 0

Harshil Patel
Harshil Patel

Reputation: 1474

struct ContentView: View {
    var body: some View {
        ScrollViewReader { proxy in
            VStack {
                Button("Jump to #50") {
                    proxy.scrollTo(50, anchor: .top)
                }

                List{
                    ForEach(0..<100) { i in
                        Text("Example \(i)")
                        .id(i)
                    }
                }
            }
        }
    }
}

Upvotes: 5

Related Questions