With the new modifier scrollTargetBehavior(.paging), ScrollViews now get paging behavior. It works great but I’ve yet to find a way to get the currently displayed view. I’ve tried using the onAppear on each view, but it doesn’t correlate to when the view is displayed, and it’s only called once. If you go back to the page it won’t be called again.
The view named PagingScrollView contains a GeometryReader to set the frame of each of the displayed child views. The view takes in a function to get the child views to be displayed.
Here is a sample complete with the preview modifier, you can just copy and paste it to xcode.
import SwiftUI
struct PagingScrollView<Content: View>: View {
var pageCount: Int
var viewForPage: (Int) -> Content
var body: some View {
GeometryReader { geo in
ScrollView (.horizontal) {
HStack (spacing: 0) {
ForEach(0..<pageCount, id:.self) { index in
viewForPage(index)
.frame(width: geo.size.width, height: geo.size.height)
}
}
.scrollTargetLayout()
}
.scrollTargetBehavior(.paging)
}
}
}
struct PreviewView: View {
var body: some View {
PagingScrollView(pageCount: 10, viewForPage: getView(index:))
}
func getView(index: Int) -> some View {
return Text("View: (index)")
}
}
#Preview {
PreviewView()
}
Is there a way to get the currently displayed view?
2
Answers
Use the
scrollPosition
modifier.Be sure to give each view in the HStack an
id
. Then, create a state variablescrolledID
(for example) and add the.scrollPosition(id: $scrolledID)
modifier on theScrollView
. In your case:This modifier can be used independently of
scrollTargetBehavior
.This is what worked with me, considering the scroll view is taking the whole screen width: