ScrollTargetBehaviorとScrollTarget

正直自分のやりたいことにそぐう機能ではなかったが、せっかく読んだのでメモしておこうと思った次第。

developer.apple.com developer.apple.com

ScrollViewはスクロールして指を離したときのスクロール速度などから最終的に終着点がどこなのか、というの計算しているらしく、その終着点を変更するのにScrollTargetBehaviorを利用する。

ScrollTargetはその終着点がどこなのか、を表す。

以下の例ではscrollTargetBehaviorViewAlignedScrollTargetBehaviorというScrollTargetBehaviorを登録している。これをしておくと、ScrollTargetがどこかのScrollView内のItemになり、そのItemがViewの左端にピッタリくっつくようになる。

(注意) ViewAlignedScrollTargetBehaviorを利用するためにはItemたちのContainerとなるViewに.scrollTargetLayout())をつけなければならないことに注意すること。

ScrollTargetBehavior & ScrollTarget · GitHub

import SwiftUI

struct SampleScrollView: View {
    private(set) var numberContainers: [NumberContainer] = []

    
    init(numbers: [Int]) {
        numberContainers = numbers.map { value in
            NumberContainer(id: value, value:  value)
        }
    }
    
    var body: some View {
        ScrollView(.horizontal) {
            HStack(spacing: 0) {
                ForEach(numberContainers) { container in
                    NumberPanel(number: container.value)
                }
            }
            .scrollTargetLayout()
        }
        .frame(width: 400)
        .scrollTargetBehavior(.viewAligned)
        .border(.gray)
        .padding(10)
    }
}

感想

自分としては、「中央に一番近いItemをScrollViewの真ん中に持ってきたい」というのがやりたいことだったのだが、自分ではちょっと難しいなと感じた。必要なこととして、

  • 1つ1つのItemの、ScrollView内での位置を取得する。
  • ScrollView内の中央の位置を取得する。
  • Itemの位置とScrollViewの中央の位置を比較して、移動させるに相応しいItemを決定する。
  • 実際に真ん中に移動させる

という操作が必要になると思うが、どれも自分の探した限りではできそうになかった。もうちょっと使いやすくならんかしらね。