この方の記事が参考になりました。
https://qiita.com/chocoyama/items/b775e80e445d81d33814
私の場合は、コードで自動的に(ユーザー操作なしで)一番下までスクロールさせようとして悩みました。
探してもなかなか引っ掛からなかったので検索の助けになれば幸いです。

コードでスクロールさせる方法
コードでスクロールさせるためには ScrollViewReader
と scrollTo
を使います。
タイミングを自由にコントロールするために onChange
も使います。
ScrollViewReader {
...
ScrollView {} // ここにスクロールさせたい View を挟む
...
.onChange() {
.scrollTo()
}
}
コード例
ポイント
-
View の中に @StateObject として コントロールする側のクラスXXXを 持っておく
@StateObject var xxx = XXX()
-
クラスXXXの中に @Published な 変数scrollIDを持っておく
@Published var scrollID: Int = 0
-
スクロールして表示させたいViewに id(...) をつけておく
- 今回は一番下のViewに付ける
id(999)
- 今回は一番下のViewに付ける
-
スクロールするView本体(ScrollView)に .onChange(...) をつけておく。
.onChange(of: xxx.scrollID) { id in ... }
-
ScrollViewを ScrollViewReader {...} で挟む
ScrollViewReader { proxy in ... }
-
onChange(...)の中に scrollTo(...) を書く
proxy.scrollTo(id)
-
scrollID が変更された時に自動的にスクロールする
self.scrollID = 999
import SwiftUI
struct ContentView: View {
@StateObject var xxx = XXX()
var body: some View {
ScrollViewReader { proxy in
ScrollView {
VStack {
Text("A")
Text("B")
Text("C")
Text("D")
Text("E")
Text("F")
Text("G")
Text("H")
Text("I")
Text("J").id(999)
}
.onAppear {
// 表示されたことを xxx に知らせる
self.xxx.onAppear()
}
}
.onChange(of: xxx.scrollID) { id in
withAnimation {
proxy.scrollTo(id)
}
}
}
}
}
class XXX: ObservableObject {
@Published var scrollID: Int = 0
func onAppear() {
// 表示された 3 秒後に scrollID を 999 に変更する
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.scrollID = 999
}
}
}
※ 初めの動画ではこのコードに加えて、わかりやすくするために色をつけたり高さを調整しています。
おまけ
-
withAnimation { ... }
を書かなければ、アニメーションなしで一瞬でスクロールできます。 -
scrollTo(id)
の代わりにscrollTo(id, anchor: ...)
を使えば、スクロールしたあとのViewの位置を細かく調整できます。
以上です。
ありがとうございました。