Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
iOS17のScrollViewはちょっとできる子
Search
toya108
September 06, 2024
30
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
iOS17のScrollViewはちょっとできる子
toya108
September 06, 2024
More Decks by toya108
See All by toya108
MaintainabilityIndexを 計測しながらコードの保守性を 改善している話
toya108
1
900
Featured
See All Featured
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
250
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
330
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
Speed Design
sergeychernyshev
33
2.1k
Designing for Performance
lara
611
70k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
490
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
The Pragmatic Product Professional
lauravandoore
37
7.4k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
890
Test your architecture with Archunit
thirion
2
2.4k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.9k
Transcript
iOS17のScrollViewは ちょっとできる子 toya108 / Toya Niibori iOSDC Japan 2024 2024/08/23
TrackB
こんにちは 👋 • クックパッド 所属の • ボルダリング が好きな • 1児の父(もうすぐ
2児) として覚えてもらえると嬉しいです toya108 / Toya Niibori
リール風UI めっちゃ流行ってませんか?
リール風UIって何? 要するにTikTok なんらかのアルゴリズムで推薦される動画、 あるいは画像のコンテンツ上下にスワイプして閲覧 できるUI 気づいたらすぐに時間が溶けるやつ
流行りのこの UI 作ってみたくないですか?
iOS17のScrollViewなら 簡単にできます!
要件から考えてみる • 画面幅いっぱいにコンテンツを表示したい • スワイプでコンテンツを切り替えたい(snap scrollの 挙動にしたい) • どのページにスワイプしたか知りたい
iOS16以前 TabViewを90度、子View側を-90度回転させると実装できる これでもできなくはないが、縦にページングしたいだけなのにやってることが 難しすぎる。 TabView { ForEach(items) { item in
ItemView(item: item) } } .tabViewStyle(PageTabViewStyle()) .rotationEffect(.degrees(90))
https://developer.apple.com/videos/play/wwdc2023/10159
どうBeyondしたか 特に重要なのはTargets and positionsで追加された以下のmodifier達 • containerRelativeFrame(_:alignment:) • scrollTargetBehavior(_:) • scrollTargetLayout(isEnabled:)
• scrollPosition(id:anchor:) これらを使用することでリール風UIが楽に作成できる
ScrollView { LazyVStack { ForEach(items) { item in ItemView(item: item)
} } } .ignoresSafeArea() 子Viewのサイズを ScrollViewのコンテナサイズにしたい iOS16まではGeometryReaderなしで子Viewに対し 親Viewのサイズに依存したサイズを指定する術がなかった
ScrollView { LazyVStack(spacing: 0) { ForEach(items) { item in ItemView(item:
item) .containerRelativeFrame([.horizontal, .vertical]) } } } containerRelativeFrame(_:alignment:) GeometryReaderなしでコンテナのサイズを指定可能に👍 ※GeometryReaderの使用を否定したいわけではない。今回の要件ではより 簡単に使用できるcontainerRelativeFrame(_:alignment:)に軍杯が上がると思う。
Snap scrollの挙動にしたい iOS16までのScrollViewは連続的なスクロールしか できない。 pagingはTabViewの領分だった。
scrollTargetBehavior(_:) ScrollView { ... } .scrollTargetBehavior(.paging) pagingやviewAlignedなど、Viewのサイズや位置を 考慮したoffsetの計算が可能に👍
scrollTargetBehavior(_:) pagingはScrollView自体のサイズを 1ページとして計算する。 ScrollView自体のサイズとコンテンツ 1ページのサイズが等しくない場合は viewAlignedが適している。 ViewAligned Paging ScrollView {
... } .scrollTargetBehavior(.viewAligned(limitBehavior: .always))
scrollTargetLayout(isEnabled:) ScrollView { LazyVStack { ... } .scrollTargetLayout() } .scrollTargetBehavior(.viewAligned(limitBehavior:
.always)) viewAlignedを使う場合は基準となるViewを指定する必要がある。 .scrollTargetLayout(isEnabled:)で指定することができる。
ここまで紹介した 機能を使うとこうなる
どのページにスワイプしたか知りたい ページ番号の表示、ログ送信などの目的で どのページへ移動したか知りたくなる。 .onAppear()で最後に表示されたViewからページを計 算することもできるが、頑張りが必要。 1 2 3 4
@State var scrollPosition: Int? = 0 var body: some View
{ ScrollView { ... } .scrollPosition(id: $scrollPosition) } scrollPosition(id:anchor:) スクロールによって表示されるViewのIDをbindできる。
scrollPosition(id:anchor:) 逆にscrollPositionを上書きすることで指定したidのViewに 移動することも可能 💪 ForEach(Array(items.enumerated()), id: \.element.id) { index, item
in Button("\(index)") { withAnimation { scrollPosition = item.id } } }
できました 🎉🎉
まとめ iOS17のScrollViewなら • 子Viewでコンテナサイズを考慮したサイズを簡単に指定できる • paging、viewAlignedなスクロールが可能 • スクロールして表示されたViewのIDが分かる さらにID指定で特定のViewまでスクロールすることができる これらの機能を使用すればリール風UIも楽に作成可能
※注意: 先にiOS16のサポートを切らないといけない リールはUIを実装するより推薦するアルゴリズムを考える方がむずい
おまけ iOS18でもScrollViewは大幅にアップデートされてる。 来年iOSDCではこのトピックで CFP書きます!!