SwiftUI Transition の基本
Transition は、ビューが画面に現れたり消えたりするときのアニメーションを定義する。if 文や ForEach でビューの表示・非表示を切り替える際に、フェードやスライドといった効果を簡単に追加できる。
transition モディファイアの基本
struct ContentView: View {
@State private var showDetail = false
var body: some View {
VStack {
if showDetail {
Text("詳細情報")
.padding()
.background(Color.blue)
.transition(.opacity)
}
Button("Toggle") {
withAnimation {
showDetail.toggle()
}
}
}
}
}.transition(.opacity) により、テキストがフェードイン・フェードアウトする。withAnimation で囲むことを忘れないこと。
組み込みの Transition
SwiftUI にはいくつかの Transition がプリセットとして用意されている。
.transition(.opacity) // フェード
.transition(.scale) // 中心から拡大縮小
.transition(.slide) // 横からスライド
.transition(.move(edge: .top)) // 指定した辺からスライド
.transition(.push(from: .bottom)) // プッシュ(iOS 16+)| opacity | 透明度が 0 から 1 に変化 |
| scale | スケールが 0 から 1 に変化 |
| slide | leading から trailing へスライド(RTL 対応) |
| move | 指定した edge からスライド |
| push | 指定方向からプッシュ(既存ビューを押し出す) |
combined で複数の Transition を組み合わせる
.transition(.opacity.combined(with: .scale))フェードとスケールが同時に適用され、より印象的な効果になる。3 つ以上も組み合わせ可能だ。
.transition(
.opacity
.combined(with: .scale)
.combined(with: .move(edge: .bottom))
)asymmetric で挿入と削除を別々に
挿入時と削除時で異なる Transition を使いたい場合は asymmetric を使う。
.transition(.asymmetric(
insertion: .move(edge: .trailing).combined(with: .opacity),
removal: .move(edge: .leading).combined(with: .opacity)
))この例では、挿入時は右からスライドイン、削除時は左へスライドアウトする。カルーセルやページ遷移のような効果に使える。
scale と anchor
scale Transition には anchor パラメータでスケールの基準点を指定できる。
.transition(.scale(scale: 0.5, anchor: .topLeading))デフォルトは .center だが、.topLeading や .bottomTrailing を指定すると、その角を基準に拡大縮小する。
Transition とアニメーションの組み合わせ
Transition 自体にアニメーションを指定することもできる。
.transition(
.scale
.animation(.spring(duration: 0.5, bounce: 0.3))
)これにより、withAnimation で指定したアニメーションとは別の動きを Transition に与えられる。
適用される条件
Transition が適用されるのは、ビューが条件分岐によって追加・削除されるときだ。
if showDetail { DetailView().transition(.slide) } のように、ビュー自体の有無が変わる場合。
.opacity(showDetail ? 1 : 0) のように、ビューは常に存在し、プロパティだけが変わる場合。これは通常のアニメーション。
ビューの出現・消失に対しては Transition を、ビューのプロパティ変更に対しては animation を使うという使い分けが基本になる。