SwiftUIでコードでViewをスクロールさせたいときは、ScrollViewReader
を使用します。
この記事では使い方を紹介します。
使い方
ScrollViewReader
は次のような形で、ScrollView
の親ビューとして使用します。ScrollViewReader
のビュービルダーにはScrollViewProxy
のインスタンスが渡されます。ScrollViewProxy
のscrollTo
メソッドを使ってスクロールできます。
コード例
//
// ContentView.swift
// Scrolling01
//
// Created by Akira Hayashi on 2024/05/18.
//
import SwiftUI
struct ContentView: View {
@Namespace var imageViewID
var body: some View {
VStack {
ScrollViewReader { proxy in
HStack {
Button(action: {
scrollToTopLeading(proxy: proxy)
}) {
Text("Top Leading")
}
Button(action: {
scrollToBottomTrailing(proxy: proxy)
}) {
Text("Bottom Trailing")
}
}
.padding()
ScrollView([.horizontal, .vertical]) {
Image("Image")
.id(imageViewID)
}
}
}
}
func scrollToTopLeading(proxy: ScrollViewProxy) {
proxy.scrollTo(imageViewID, anchor: .topLeading)
}
func scrollToBottomTrailing(proxy: ScrollViewProxy) {
proxy.scrollTo(imageViewID, anchor: .bottomTrailing)
}
}
#Preview {
ContentView()
}
左上と右下へのスクロール
コードからスクロールさせるには、次のようにscrollTo
メソッドを使います。
proxy.scrollTo(imageViewID, anchor: .bottomTrailing)
最初の引数はどのビューまでスクロールさせるかをID
で指定します。ID
を取得するために、次のようにid
モディファイアを使っています。
@Namespace var imageViewID
Image("Image")
.id(imageViewID)
ビューのどこにスクロールさせるのかを指定するのが、引数 anchor
です。色々ありますが、このサンプルでは.topLeading
で左上、.bottomTrailing
で右下にスクロールさせています。
垂直方向のみスクロール可能なビューであれば、.top
で先頭、.bottom
で末尾などを指定します。
TextEditorのときは?
TextEditor
ビューは自分自身でスクロール可能なのですが、ScrollViewReader
でスクロールさせるには、本来は不要なScrollView
を配置する必要があります。
@State private var fullText: String = ""
ScrollViewReader { proxy in
ScrollView {
TextEditor($fullText)
}
}
どんなところで使ったことがあるか
筆者の場合は、SwiftUIでログを表示するビューを作った時に使用しました。ログが追加されたときに自動的に最新のログを表示するためには、自動的に末尾にスクロールさせる必要がありました。そこで、使用しました。