Simultaneously Scrolling SwiftUI ScrollViews Using Introspect
Build intuitive user interfaces

Simultaneous scrolling UIScrollView
using UIKit
can easily be achieved by using the UIScrollViewDelegate
. The idea is pretty simple: Observe the contentOffset
of a UIScrollView
and apply it to another one when the value changes.
However, SwiftUI
currently doesn’t provide an API to achieve the very same.
At least iOS 14
there is a new API to do something similar but it’s not enough to replicate the desired use-case:
Enabling simultaneously scrolling ScrollView
s in SwiftUI
As there are no APIs to enable this 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.
After adding Introspect
to your project, you can access UIKit
elements like this:
With that, we can now implement a component for simultaneously scrolling UIScrollView
s.
For simplicity let’s call this component SimultaneoulsyScrollViewHandler
. We need to register all the UIScrollViews
we want to synchronize in this component to be able to observe and adjust their contentOffset
s.
Find a ready to use Swift Package here: SimultaneouslyScrollView
Now we need to get notified about contentOffset
changes of the UIScrollView
s of our array and apply it to all other registered UIScrollView
s.
We can achive this by implementing the UIScrollViewDelegate
:
With this new component, we can now go back to our SwiftUI
View
and using it in introspectScrollView
as following:
See it in action:

Where to go from here?
I recommend storing the simultaneouslyScrollViewHandler
inside some view-model. E.g. an @ObservedObject
or a @StateObject
.
The above implementation contains a few issues.
One is that the scrollViews
Array
never get’s cleared and will retain all UIScrollView
s from all the redraws of SwiftUI
. This can be solved by using some sort of a weak-reference-store.
This and other improvements can be found on a final implementation on my GitHub profile: