SwiftUI List in ScrollView

Mastering ScrollView in SwiftUI

We had the scroll view from the very first version of SwiftUI. It was quite limited. But this year changed everything when Apple released ScrollViewReader during WWDC 20. This week we will learn all about scroll views in SwiftUI. We will learn how to scroll to the particular position and read the current offset of scroll view content.

Basics

The usage of a scroll view is pretty simple. You create a scroll view and pass the content inside a ViewBuilder closure. Lets take a look at the first example.

import SwiftUI struct ContentView1: View { var body: some View { ScrollView { ForEach[0.. Void = { _ in }, @ViewBuilder content: [] -> Content ] { self.axes = axes self.showsIndicators = showsIndicators self.offsetChanged = offsetChanged self.content = content[] } }

As you can see, we have a pretty similar to SwiftUIs scroll view definition. It uses the same parameters but also adds offsetChanged closure that we will call whenever content offset changes. Lets move to the body property implementation of our scroll view.

struct ScrollView: View { // ... var body: some View { SwiftUI.ScrollView[axes, showsIndicators: showsIndicators] { GeometryReader { geometry in Color.clear.preference[ key: ScrollOffsetPreferenceKey.self, value: geometry.frame[in: .named["scrollView"]].origin ] }.frame[width: 0, height: 0] content } .coordinateSpace[name: "scrollView"] .onPreferenceChange[ScrollOffsetPreferenceKey.self, perform: offsetChanged] } }

As I said before, we use SwiftUIs scroll view under the hood and pass all the parameters to configure its behavior. Before adding the content, we place a GeometryReader view that allows us to track the content offset changes. We use preferences to pass the origin point of our content to the parent view.

To learn more about GeometryReader, look at my Building BarChart with Shape API in SwiftUI post.

struct ContentView: View { var body: some View { ScrollView[ axes: [.horizontal, .vertical], showsIndicators: false, offsetChanged: { print[$0] } ] { ForEach[0..

Chủ Đề