Search code examples
iosswiftuiswiftui-listswiftui-scrollview

SwiftUI enable scrolling of List inside a disabled ScrollView


I have a List inside a ScrollView that is scroll disabled. The List also disables and cannot be enabled. I need the ScrollView to not scroll by drag gesture. Is there a way to allow the List to scroll but the parent ScrollView to have scrolling disabled?

Here is an example.

struct TestScroll: View {
    @State var scrollId: String = "first"
    var body: some View {
        GeometryReader { geoProxy in
            VStack {
                ScrollView(.horizontal) {
                    ScrollViewReader { scrollProxy in
                        HStack {
                            List(0..<25) { index in
                                Text("Item-\(index)")
                            }
                            .scrollDisabled(false) // <- This is ignored
                            .frame(width: geoProxy.frame(in: .global).size.width)
                            .id("first")
                            Text("Second View")
                                .frame(width: geoProxy.frame(in: .global).size.width)
                                .id("second")
                            Text("Third View")
                                .frame(width: geoProxy.frame(in: .global).size.width)
                                .id("third")
                        }
                        .onChange(of: scrollId, perform: { value in
                            scrollProxy.scrollTo(value)
                        })
                    }
                    .tabViewStyle(.page(indexDisplayMode: .never))
                }
                .scrollDisabled(true) // <- Disables all scrolling
                HStack(spacing: 20.0) {
                    Button("First View", action: {scrollId = "first"})
                    Button("Second View", action: {scrollId = "second"})
                    Button("Third View", action: {scrollId = "third"})
                }
            }
        }
    }
}

Solution

  • I cannot reproduce this on iOS 17.4, but I can reproduce this on iOS 16.4, so presumably Apple fixed it somewhere in between.

    In iOS 16.4, you can directly set the isScrollEnabled environment value to make this work. Replace

    .scrollDisabled(false)
    

    with

    .environment(\.isScrollEnabled, true)