SwiftUIでViewをスクロールさせる

SwiftUIでコードでViewをスクロールさせたいときは、ScrollViewReaderを使用します。

この記事では使い方を紹介します。

目次

使い方

ScrollViewReaderは次のような形で、ScrollViewの親ビューとして使用します。ScrollViewReaderのビュービルダーにはScrollViewProxyのインスタンスが渡されます。ScrollViewProxyscrollToメソッドを使ってスクロールできます。

コード例

//
//  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でログを表示するビューを作った時に使用しました。ログが追加されたときに自動的に最新のログを表示するためには、自動的に末尾にスクロールさせる必要がありました。そこで、使用しました。

著書紹介

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Akira Hayashi (林 晃)のアバター Akira Hayashi (林 晃) Representative(代表), Software Engineer(ソフトウェアエンジニア)

アールケー開発代表。Appleプラットフォーム向けの開発を専門としているソフトウェアエンジニア。ソフトウェアの受託開発、技術書執筆、技術指導・セミナー講師。note, Medium, LinkedIn
-
Representative of RK Kaihatsu. Software Engineer Specializing in Development for the Apple Platform. Specializing in contract software development, technical writing, and serving as a tech workshop lecturer. note, Medium, LinkedIn

目次