siteline/swiftui-introspect

ScrollView - .isScrollEnabled = false doesn't work

theedov opened this issue · 1 comments

Description

Setting .isScrollEnabled with introspect doesn't seem to work.

#Preview {
    ScrollView {
        Rectangle()
            .fill(.red)
            .frame(minHeight: 250)
        Rectangle()
            .fill(.yellow)
            .frame(minHeight: 250)
        Rectangle()
            .fill(.blue)
            .frame(minHeight: 250)
        Rectangle()
            .fill(.pink)
            .frame(minHeight: 250)
        Rectangle()
            .fill(.teal)
            .frame(minHeight: 250)
    }
    .introspect(.scrollView, on: .iOS(.v15, .v16, .v17)) { scrollView in
        scrollView.isScrollEnabled = false
    }
}

But it works if instead of .scrollView I use .list.

#Preview {
    ScrollView {
        Rectangle()
            .fill(.red)
            .frame(minHeight: 250)
        Rectangle()
            .fill(.yellow)
            .frame(minHeight: 250)
        Rectangle()
            .fill(.blue)
            .frame(minHeight: 250)
        Rectangle()
            .fill(.pink)
            .frame(minHeight: 250)
        Rectangle()
            .fill(.teal)
            .frame(minHeight: 250)
    }
    .introspect(.list, on: .iOS(.v15, .v16, .v17)) { list in
        list.isScrollEnabled = false
    }
}

Checklist

Expected behavior

Setting isScrollEnabled should work when setting for .scrollView

.introspect(.scrollView, on: .iOS(.v15, .v16, .v17)) { scrollView in
       scrollView.isScrollEnabled = false
}

Actual behavior

Currently only works if set for .list.

.introspect(.list, on: .iOS(.v15, .v16, .v17)) { list in
       list.isScrollEnabled = false
}

Steps to reproduce

No response

Version information

1.0.0

Destination operating system

iOS 17

Xcode version information

Version 15.0 (15A240d)

Swift Compiler version information

swift-driver version: 1.87.1 Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1)
Target: arm64-apple-macosx14.0

This is not a bug in SwiftUI Introspect.

SwiftUI’s internally managed state always overrides arbitrarily set state.

In this case, the fact that there’s a .scrollDisabled(true) means you should be using that as opposed to dropping down to UIKit level, because SwiftUI will end up overriding you every time.

As a general rule, whenever there is a built-in modifier for something, you should be using that every time. Introspection is only suitable for areas of UIKit that haven’t been surfaced up in SwiftUI’s API.

For your specific case, because scrollDisabled is only available on iOS 16 and after, if you need to support iOS 15 you should be introspecting that specific version and setting isScrollEnabled there. You could even come up with a custom modifier that uses the right method (introspection vs built-in modifier) depending on which OS version you’re running on. Should be trivial.