ScrollView with multiple LazyVGrids jumping around when using .scrollPosition

25 Views Asked by At

I am using macOS.

I have multiple LazyVGrid in my ScrollView. I am using .scrollPosition() to track the scroll position. Without using this modifier, I don't have any issues, but if, the scrolling is broken.

The problem is similiar to this one: Add multiple LazyVGrid to ScrollView

Unfortunately, I cannot use this solution, because my Grids definitely have different heights and this will cause the problem.

Here is an example code:

struct ContentView: View {
    
    @State var scrollPosition: UUID? = nil
    
    struct MyStruct: Identifiable {
        let id = UUID()
        let text: String
        let uneven: Bool
    }
        
    @State var elements: [MyStruct]
    
    init() {
        var el = [MyStruct]()
        for i in 1..<30 {
            el.append(MyStruct(text: "Item\(i)", uneven: i % 2 == 0))
        }
        self.elements = el
    }
    
    var body: some View {
        
        VStack {
            
            
            ScrollView(.vertical) {
                
                LazyVStack {
                    
                    ForEach(self.elements) { element in
                        VStack {
                            Text(element.text)
                            LazyVGrid(columns: Array(repeating: GridItem(.fixed(30)), count: 7), content: {
                                ForEach(0..<7 * (element.uneven == true ? 6 : 7), id: \.self) { index in
                                    Text("\(index)")
                                }
                            })
                            .padding(.bottom, 20)
                        }
                    }
                    
                }   // end LazVStack
                .scrollTargetLayout()
                .frame(width: 600)
                
            }
            .scrollPosition(id: self.$scrollPosition)
        }
        
    }
    
}

You will experience the problem when you completely scroll down the list and then scroll up. Scrolling up is not possible anymore.

If you remove the .scrollPosition-modifier, it works. If you change the ForEach line to this:

ForEach(0..<7 * 7, id: \.self) { index in

it will work too, because then every Grid has the same height.

Adding a fake row will solve the problem, but it will also leave some extra space. Adding a negative padding or offset will not help, it will cause the problem again.

I am sure, that this is a bug in SwiftUI and I will file it. But because Apple barely fixes such bugs, does anyone has an idea for a workaround?

0

There are 0 best solutions below