Is that possible to scroll a LazyVGrid to show a particular item in the middle?

312 views Asked by At

I have this LazyVGrid showing a grid with 4 columns and countless icons.

private var columns: [GridItem] = [
  GridItem(.adaptive(minimum: .infinity, maximum: .infinity), spacing: 0),
  GridItem(.adaptive(minimum: .infinity, maximum: .infinity), spacing: 0),
  GridItem(.adaptive(minimum: .infinity, maximum: .infinity), spacing: 0),
  GridItem(.adaptive(minimum: .infinity, maximum: .infinity), spacing: 0)
]

var body: some View {
  ScrollView{ //{ proxy in
    ZStack{
        Color.blue
        
        LazyVGrid(
          columns: columns,
          alignment: .center,
          spacing: 10,
          pinnedViews: []
        ) {
          ForEach(items, id:\.self.title) { item in
            Text(item.title)
              .listRowBackground(Color.clear)
              .id(item.title)
              .padding(.horizontal, 15)
          }
        }
        .listStyle(PlainListStyle())
      }
    }
}

Now I want to scroll down the grid, programmatically, to show a particular item.

Is that possible to do that on a Grid?

Lists can do that easily but what about LazyVGrids?

1

There are 1 answers

2
son On BEST ANSWER

The simplest way is to wrap inside ScrollViewReader and change ForEach to iterate through array by index. I made an array mocked with numbers in range 0...200, and created a button to scroll to element at index 120.

var body: some View {
    ScrollViewReader { proxy in
        ScrollView {
            VStack {
                Button {
                    withAnimation {
                        proxy.scrollTo(120, anchor: .center)
                    }
                } label: {
                    Text("Scroll")
                }
                
                ZStack {
                    Color.blue
                    
                    LazyVGrid(
                        columns: columns,
                        alignment: .center,
                        spacing: 10,
                        pinnedViews: []
                    ) {
                        //Iterating by index in this example, should use id instead
                        ForEach(0..<items.count, id: \.self) { i in
                            Text(items[i].title)
                                .listRowBackground(Color.clear)
                                .id(i) //<- put index here
                                .padding(.horizontal, 15)
                        }
                    }
                    .listStyle(PlainListStyle())
                }
            }
        }
    }
}

Output:

enter image description here