SimultaneouslyScrollView
Simultaneously scrolling ScrollViews with SwiftUI support
Installation
Using Swift Package Manager
Swift Package Manager is a tool for managing the distribution of Swift frameworks. It integrates with the Swift build system to automate the process of downloading, compiling, and linking dependencies.
Using Xcode
To integrate using Xcode 13, open your Project file and specify it in Project > Package Dependencies using the following URL:
https://github.com/stonko1994/SimultaneouslyScrollView.git
Usage
import SimultaneouslyScrollView
Synchronize multiple UIScrollViews
- Create an
SimultaneouslyScrollViewHandlerinstance by using the factory method and the create function:let simultaneouslyScrollViewHandler = SimultaneouslyScrollViewHandlerFactory.create()
- Register
UIScrollViewsthat should be synchronized:simultaneouslyScrollViewHandler.register(scrollView: scrollView)
SwiftUI support
To enable simultaneously scrolling in SwiftUI we need to utilize another library that allows access to the underlying UIScrollView for a SwiftUI.ScrollView.
Synchronize multiple ScrollViews
-
Follow the installataion steps from SwiftUI-Introspect
-
Import
Introspectin addition toSimultaneouslyScrollViewimport SimultaneouslyScrollView import Introspect
-
Access the
UIScrollViewfrom yourScrollViewand register it to theSimultaneouslyScrollViewHandler.ScrollView { ... } .introspectScrollView { simultaneouslyScrollViewHandler.register(scrollView: $0) } -
That's it
🥳 🎉 I recommend storing the
simultaneouslyScrollViewHandlerinside some view-model. E.g. an@ObservedObjector a@StateObject.
How it works
SwiftUI doesn't provide any API to specify the contentOffset for ScrollViews. Therefore we need to access the underlying UIKit element and set the contentOffset there. This is where SwiftUI-Introspect comes in handy by providing access to the UIKit elements.
As every redraw of the View creates a new ScrollView and a new UIScrollView instance, it is important not to store strong references of the registered UIScrollViews. The SimultaneouslyScrollViewHandler manages this using a custom implementation using the WeakObjectStore.
When a ScrollView is scrolled by the user, the SimultaneouslyScrollViewHandler gets notified about this via the UIScrollViewDelegate. When this happens, the contentOffset of every other registered UIScrollView will be adapted to the new contentOffset of the currently scrolled UIScrollView.
Example
I use this package in one of my own Apps that is currently in the Appstore. So there shouldn't be any issues using this in any production code except the possibility that new SwiftUI versions could break SwiftUI-Introspect.
Please note that this introspection method might break in future SwiftUI releases. Future implementations might not use the same hierarchy, or might not use UIKit elements that are being looked for. Though the library is unlikely to crash, the .introspect() method will not be called in those cases.
Download Scoretastic


