本セッションは、SwiftUIにおける GeometryReader と ScrollView の基礎から応用までを体系的に整理し、複雑なUI表現をいかに設計・実装するかを具体例と共に解説したものです。
1. 背景と課題
- GeometryReaderの難しさ:座標基準の分かりづらさやデバッグの困難さ。
- ScrollViewDelegate的な発想:UIKitとの違いに戸惑い、Viewの重なりや処理トリガー整理が必要。
- サンプル不足:ちょうど良い難易度の実装例が少なく、学習・応用が難しい。
2. GeometryReaderの活用事例
- スクロールに応じたヘッダー縮小・拡大(Parallax効果・FontSize調整)。
- 背景のParallax効果(スクロール位置に応じたScale/Offset制御)。
- レスポンシブなレイアウト調整(widthに応じてGrid列数を変更)。
3. 応用的な実装例
- 日付タブ切替UI(DroidKaigiでの事例)
- AndroidのCoordinatorLayout+TabLayoutの動きをSwiftUIで模倣。
- GeometryReader+PreferenceKeyでOffset値を監視し、タブ背景や下線を滑らかに補間。
- お気に入り追加時のハートアニメーション
- GeometryReaderでタップ位置を取得し、ZStackに重ねたImageを@Stateで制御。
- DragGestureを利用してボタン操作を再現し、滑らかな動きを実装。
- 横スクロール型タブ+コンテンツ切替
- ScrollView(.horizontal)+LazyHStackと@Stateを組み合わせて、タブとコンテンツを双方向に同期。
- 線形補間を応用し、自然な下線移動と文字幅調整を実現。
- サムネイル自動カルーセル
- ScrollPositionとTimerを組み合わせて無限スクロールを実現。
- iOS18新Modifier(onScrollPhaseChange / onScrollGeometryChange)でユーザー操作と自動スクロールを自然に両立。
4. 設計の指針
- GeometryReaderは「値取り専用」に割り切る:
- 必要最小限の値を取得し、State/ViewModelに閉じ込めて副作用を抑制。
- ScrollViewは新Modifierを主役に宣言的に扱う:
- scrollPosition/scrollTargetLayout/scrollTargetBehaviorでページングや位置管理を簡潔に。
- 複雑なUIは「値 → 状態 → 見た目」に分解:
- ZStackで固定物
- ScrollView+Lazy系でリスト/タブ
- GeometryReader値はまず状態に変換し、最終的なUIは補間やアニメーションで調整。
5. まとめ
SwiftUIはiOS17/18で強化されたScrollView系Modifierを組み合わせることで、GeometryReader頼みの実装から進化しつつある。ただし、依然として Parallax・レスポンシブ対応・複雑なタブ構造 などではGeometryReaderが重要な役割を果たす。本セッションでは、その実践的なアプローチと具体コード例を通じて、「複雑UIを整理し、保守性とパフォーマンスを両立させる」 実装の勘どころが示された。