1

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-

  • onAppear gets called twice or more sometimes.
  • onAppear doesnt get triggered when i just begin to scroll and cancels the scroll.

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

2
  • 1
    try using .scrollPosition(id....), see: developer.apple.com/documentation/swiftui/view/… Commented Mar 3, 2024 at 0:59
  • I know about scrollposition already,but dont know how to bind the current verse item in the code i provided. Could you write the code and help Commented Mar 3, 2024 at 5:36

1 Answer 1

6

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)
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

it worked..thanks a lot..if you dont mind, can you help me with my latest question too?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.