Jaseel.Dev
Jaseel.Dev

Reputation: 769

Get current item in LazyVstack inside scrollview when scroll ends

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

Upvotes: 0

Views: 570

Answers (1)

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)
    }
}

Upvotes: 5

Related Questions