LoginSignup
5
5

More than 3 years have passed since last update.

【SwiftUI】 ListでOffsetを取得する

Last updated at Posted at 2020-05-26

SwiftUIのListは、UIKitのTableViewよりも簡単にリストを構築できるようになって嬉しいです。
しかし、offsetが今までのように簡単に取得できなかったので、カスタムListを作ってみました。

使い方

struct ContentView: View {
    @State private var offset: CGFloat = 0

    var body: some View {

        TrackableList(contentOffset: $offset) {

            ForEach(0..<100) { _ in
                Text("offset:\(self.offset)")
            }
        }
    }
}

画面収録 2020-05-27 6.54.03.mov.gif

Offset取得可能なカスタムListを作る

struct TrackableList<Content>: View where Content: View {
    @Binding var contentOffset: CGFloat
    let content: Content

    init(contentOffset: Binding<CGFloat>, @ViewBuilder content: () -> Content) {
        self._contentOffset = contentOffset
        self.content = content()
    }

    var body: some View {
        GeometryReader { outsideProxy in
            List {
                ZStack {
                    GeometryReader { insideProxy in
                        Color.clear
                            .preference(key: ScrollOffsetPreferenceKey.self, value: [outsideProxy.frame(in: .global).minY - insideProxy.frame(in: .global).minY])
                            // Send value to the parent
                    }
                    VStack {
                        self.content
                    }
                }
            }
            .onPreferenceChange(ScrollOffsetPreferenceKey.self) { value in
                self.contentOffset = value[0]
            }
            // Get the value then assign to offset binding
        }
    }
}

struct ScrollOffsetPreferenceKey: PreferenceKey {
    typealias Value = [CGFloat]

    static var defaultValue: [CGFloat] = [0]

    static func reduce(value: inout [CGFloat], nextValue: () -> [CGFloat]) {
        value.append(contentsOf: nextValue())
    }
}

Viewの外側と内側にそれぞれGeometryReaderを置き、その差し分を計算することでoffsetを取得しています。

参考

こちらの記事を参考にしました。
以下記事では、Listではなく、ScrollViewのoffsetを取得しています。
horizontalverticalshowIndicatorsなどの設定もできるようになっています。
https://medium.com/@maxnatchanon/swiftui-how-to-get-content-offset-from-scrollview-5ce1f84603ec

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5