I want to print the currently displayed item in LazyVStack which is inside scrollview with paging enabled.
i have tried printing in onAppear of VerseView The issues with printing inside onAppear are-
I SIMPLY WANT TO PRINT THE CURRENT ITEM WHICH IS DISPLAYED IN SCREEN WHENEVER I RELEASES THE SCROLL.
CODE IS :
struct SwippableView: View {
var data: [VerseModel]
var body: some View {
ScrollView(.vertical) {
LazyVStack(spacing: 0) {
ForEach(data, id: \.id) { verse in
VerseView(verse: verse)
.padding(0)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}.scrollTargetLayout()
}
.ignoresSafeArea()
.scrollTargetBehavior(.paging)
.scrollIndicators(.never)
}
}
Additional info: Each view inside LazyVStack fills the entire screen
Try this approach using .scrollPosition
and a .onChange
to print
the current verse that is on the screen when scrolling.
struct ContentView: View {
// --- for testing
let verses = [VerseModel(id: 1, verse: "verse-1"), VerseModel(id: 2, verse: "verse-2"), VerseModel(id: 3, verse: "verse-3")]
var body: some View {
SwippableView(data: verses)
}
}
// --- for testing
struct VerseModel: Identifiable, Hashable {
let id: Int
var verse: String
}
struct SwippableView: View {
var data: [VerseModel]
@State var scrolledID: Int? // <--- here
var body: some View {
Text("\(scrolledID ?? 1)") // <--- for testing
ScrollView(.vertical) {
LazyVStack(spacing: 0) {
ForEach(data, id: \.id) { verse in
VerseView(verse: verse)
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}.scrollTargetLayout()
}
.ignoresSafeArea()
.scrollTargetBehavior(.paging)
.scrollIndicators(.never)
.scrollPosition(id: $scrolledID) // <--- here
.onChange(of: scrolledID) {
print("----> scrolledID: \(scrolledID)") // <--- here
}
}
}
// --- for testing
struct VerseView: View {
var verse: VerseModel
var body: some View {
ZStack {
Rectangle().fill(Color.red.opacity(0.3))
Text(verse.verse)
}.frame(width: 333, height: 666)
}
}