SwiftUI Scrolling Control from Parent View: How to Scroll to Bottom?

After typing in message and pressing the “Send” button, the keyboard disappears and the message display should now scroll up to show the newly sent message, which is typically at the very bottom of the scrollView right above the text field.

Scrolling Up Programmatically is easy. Understanding it is big step towards knowing how SwiftUI works.

This is tremendously helpful and with additional few ingredients forms an elegant solution.

I organized below the 7 necessary steps, backwards from the actual scrolling to how the scrolling gets triggered by the parent view. I think this is the best way to appreciate how the system works and be able to debug if anything goes wrong:

  1. Each row of the ScrollView must have a “.id(index)” — without this tag, the scrollTo method will not know where to scroll to. Unfortunately, if we leave this step out, there will be no compile or run-time error, just that the scrollView will be move at all when scrollTo gets triggered.
  2. “.onChange” attached to the loop, inside the scrollView — this is the final piece of the listener that will activate the scrollTo action. This has to be inside the scrollView in order to be able to call the scrollView.scrollTo method.

3. ObservedObject variable for the .onChange to monitor — this is how .onChange gets triggered. Easiest is to use a boolean, which can be toggled to cause the desired scrolling to bottom. For example:

At the top of the file, declare “@ObservedObject var state:ScrollTrigger”

4. ScrollTrigger class needs to be defined:

5. In the parent view, also add an ObservedObject, so that it can be passed the the child view for purpose of sending an “update” toggle:

6. When including the child view in the parent view, make sure that this “state” variable is shared with the child:

In this way, the two variables “state” in the parent and child views are connected, such that changing the value “state” in the parent will trigger the “onChange” in the child view.

7. All done, by calling “self.state.update()” in the parent view, the scrolling in the child view will be triggered.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store