はじめに
Webサイトとかだとよく見る、スクロールするとふわっとコンテンツが下から現れるあれをiOSで実装してみます。
サンプルアプリ
実装
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollView {
VStack(spacing: 20) {
ForEach(0..<30) { index in
GroupBox("新機能\(index)") {
Text("サンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキストサンプルテキスト")
}
.scrollTransition(.animated, axis: .vertical) { visualEffect, transitionPhase in
visualEffect
.opacity(0 < transitionPhase.value ? 0.0 : 1.0)
.offset(y: 0 < transitionPhase.value ? 0.0 : -40.0)
}
}
}
.padding()
}
}
}
解説
transitionPhase
の型はScrollTransitionPhase
で列挙型です。
- identity
- topLeading
- bottomTrailing
上記の3つのcaseがあります。
ドキュメントを読むと以下のような判定だということがわかります。
identity |
ScrollViewの可視領域内(中心付近)にコンテンツがあるときに適用される |
topLeading |
ScrollView(.vertical)の時は上端、ScrollView(.horizontal)の時は左端にコンテンツがあるときに適用される |
bottomTrailing |
ScrollView(.vertical)の時は下端、ScrollView(.horizontal)の時は右端にコンテンツがあるときに適用される |
では、今回使用しているtransitionPhase.value
はなんなのでしょうか?
これはtopLeading
を-1.0、identity
を0、bottomTrailing
を1.0としてDoubleで出力してくれるプロパティです。
ここまでわかるとコードで何をしているのかを理解しやすくなると思います。
ちなみに以下のコードでも同じことができます。
.scrollTransition(.animated, axis: .vertical) { visualEffect, transitionPhase in
visualEffect
.opacity(transitionPhase == .bottomTrailing ? 0.0 : 1.0)
.offset(y: transitionPhase == .bottomTrailing ? 0.0 : -40.0)
}
おわり
ScrollViewのアニメーションの幅がかなり広がりましたね