SwiftUIScrollOffset

1.3.5

Read and update the scroll offset of a SwiftUI List or ScrollView from anywhere in the view hierarchy
ciaranrobrien/SwiftUIScrollOffset

What's New

v1.3.5

2024-04-25T07:57:58Z

Fixed scrollTo always animating on macOS.

SwiftUI Scroll Offset

Read and update the scroll offset of a SwiftUI List or ScrollView from anywhere in the view hierarchy.

Get Started

Use the scrollOffsetID modifier to allow any child view to read the first scroll container's offset.

struct ContentView: View {
    var body: some View {
        ScrollView {
            ChildView()
        }
        .overlay(ChildView())
        .scrollOffsetID(.automatic)
    }
}

Use ScrollOffset to read the scroll offset from the provided edge. The scroll offset is calculated relative to any safe area insets.

struct ChildView: View {
    @ScrollOffset(.top) private var scrollOffset
    
    var body: some View {
        Text(verbatim: "\(scrollOffset)")
    }
}

Provide a range to ScrollOffset to clamp the scroll offset. This prevents view updates for changes outside of this range.

@ScrollOffset(.top, in: -20...0) private var scrollOffset

Advanced Usage

Provide a unique identifier to scrollOffsetID to read the scroll offset from anywhere in the view hierarchy. Use the projectedValue of ScrollOffset to programmatically scroll to an offset.

struct ContentView: View {
    var body: some View {
        VStack {
            ScrollView {
                Rectangle()
                    .fill(.blue.opacity(0.1))
                    .frame(height: 1200)
            }
            .scrollOffsetID("Foo")
            
            SiblingView()
                .padding()
        }
    }
}


struct SiblingView: View {
    @ScrollOffset(.top, id: "Foo") private var scrollOffset
    
    var body: some View {
        Text(verbatim: "\(scrollOffset)")
        
        Button("Scroll to Top") {
            $scrollOffset.scrollTo(.zero, withAnimation: true)
        }
    }
}

Use ScrollOffsetProxy to read an offset, or programmatically scroll to an offset, without view updates when the offset changes.

struct ContentView: View {
    @ScrollOffsetProxy(.bottom, id: "Foo") private var scrollOffsetProxy
    
    var body: some View {
        VStack {
            List {
                Section {
                    ForEach(0..<100) { number in
                        Text(verbatim: "\(number)")
                    }
                }
            }
            .scrollOffsetID("Foo")
            
            Button("Scroll to Bottom") {
                scrollOffsetProxy.scrollTo(.zero, withAnimation: true)
            }
            .padding()
        }
    }
}

Requirements

  • iOS 14.0+, macOS 11.0+, tvOS 14.0+, visionOS 1.0+
  • Xcode 15.0+

Installation

Dependencies

Contact

@ciaranrobrien on Twitter.

Description

  • Swift Tools 5.10.0
View More Packages from this Author

Dependencies

Last updated: Mon Apr 29 2024 09:30:21 GMT-0900 (Hawaii-Aleutian Daylight Time)