onAppearで表示してもタイミング的にだめな時ってあるよね。今回は、遷移した際で、特定位置を画面の上部にスクロールさせてから、表示したかったのだが、移動するのが見えてしまうので、その対応策をメモしておきます
時間を少しあけてから、画面を表示というより見えるようにする
今回やりたいのは以下のような感じ。
前提として、遷移先にはtwitterのタイムラインのようにアイテムが並んでいて、
特定のアイテムが画面上部にきた状態で遷移したい。
ところが、ScrollViewReaderで移動させたとしても、遷移した直後に遷移させると、
他がレンダリングできていない状態なので、思った場所にスクロールしてくれない。
なので、scrollを0.2秒遅延させて実行すると、位置はいいが、遷移した後、最初に通常の場所で表示され、0.1秒後に希望の場所に移動してると、大変ださいことになっている。
@State private var isReady = false
var body: some View {
ScrollViewReader { proxy in
ScrollView {
VStack {
ForEach(items, id: \.self) { item in
Text("Item \(item)")
.id(item)
.opacity(isReady ? 1 : 0) // 初期は非表示
}
}
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
proxy.scrollTo(items.last, anchor: .top)
isReady = true // 完全にスクロールした後に表示
}
}
}
}
ひとまず、0.1秒後にスクロールさせるので、位置は問題ない。
ただ、表示タイミングに問題があるので、スクロールを実行した後、
画面を透明から表示にさせるよう、opacityで制御する。
これで、遷移した後の画面がぱっと表示されるようになった
よかったね