iOS version: 17.0
My goal is to implement a vertical paging behaviour in ScrollView that satisfies these conditions:
- vertical size of every page should be vertical screen size – size of the tab bar
- It should have a quick snapping animation for every page, it cannot skip any pages
- the tab bar doesn’t have to be transparent, I don’t care about the visibility of the content behind the tab bar
This is an illustration of what I want to achieve:
I implemented 2 versions of the code, but non of them can satisfy all the conditions:
1 version, using .paging behaviour:
struct CardView: View {
var color: Color
var body: some View {
RoundedRectangle(cornerRadius: 10)
.fill(color)
}
}
struct ContentView: View {
let randomColors: [Color] = [
.red,
.green,
.blue,
.yellow,
.orange
]
var body: some View {
TabView {
ScrollView {
LazyVStack(spacing: 0) {
ForEach(randomColors, id: .self) { color in
CardView(color: color)
.containerRelativeFrame(.horizontal)
.containerRelativeFrame(.vertical)
}
}
}
.ignoresSafeArea(.container, edges: .top)
.scrollTargetBehavior(.paging)
.scrollIndicators(.never)
.tabItem {
Label("ScrollView", systemImage: "1.circle")
}
}
}
}
How it works:
You can see here that scrolling offset is not correct, it scrolls more points than needed.
Also I didn’t find any way to explicitly configure the size of scrollable page.
2 version, using .viewAligned:
struct ContentView: View {
let randomColors: [Color] = [
.red,
.green,
.blue,
.yellow,
.orange
]
var body: some View {
TabView {
ScrollView {
LazyVStack(spacing: 0) {
ForEach(randomColors, id: .self) { color in
CardView(color: color)
.containerRelativeFrame(.horizontal)
.containerRelativeFrame(.vertical)
.scrollTargetLayout()
}
}
.scrollTargetLayout()
}
.ignoresSafeArea(.container, edges: .top)
.scrollTargetBehavior(.viewAligned)
.scrollIndicators(.never)
.tabItem {
Label("ScrollView", systemImage: "1.circle")
}
}
}
}
How it works:
Have to provide s link, as stackoverflow doesn’t let me to upload gif for some reason, though it is of correct size and resolution
https://raw.githubusercontent.com/PavelKatunin/public_test_files/refs/heads/main/ezgif-3-28a1575f7b.gif
You can see that the animation is too slow, and also it can skip some of the pages.
I tried many different approaches, tried to use content insets and margins, and also tried to implement some UIKit logic of UIScrollView. It never worked.
Is there a reliable way to configure pagination offsets and snapping animation velocity?
1