swiftswiftuiuiscrollviewscrollview

How to detect user scrolll on the scrollview


i want to detect when the user scroll on the scrollview and above a certain scroll item show up a button, i wrote this code on my up looking online some example but there is no printout on the change of scrollID, why??

ScrollView {
    LazyVGrid(columns: columns) {
        ForEach(group) { g in
            NavigationLink {
                Text("Details")
            } label: {
                VStack {
                    Image(systemName: "tv") // Replace with actual images
                        .resizable()
                        .scaledToFit()
                        .frame(width: reader.size.width/3, height: 50)
                        .padding()
                        .background(Color.gray.opacity(0.2))
                        .cornerRadius(10)
                    Text("List")
                        .bold()
                        .font(.subheadline)
                }
                .foregroundStyle(.white)
            }
        }
    }
    .scrollTargetLayout()
}
.scrollPosition(id: $scrollID)

Solution

  • I tried your example, improvising the parts that were missing.

    It works for me. The IDs of the items in the first column of the LazyVGrid are printed when the grid is scrolled. So the problem may be somewhere in the code you didn't post.

    Here is the updated (working) example:

    struct ContentView: View {
    
        struct Group: Identifiable {
            let id = UUID()
        }
    
        let columns = [GridItem(.flexible()), GridItem(.flexible())]
        let group: [Group]
        @State private var scrollID: Group.ID?
    
        init() {
            var groups = [Group]()
            for i in 0..<100 {
                groups.append(Group())
            }
            self.group = groups
        }
    
        var body: some View {
            GeometryReader { reader in
                ScrollView {
                    LazyVGrid(columns: columns) {
                        ForEach(group) { g in
                            NavigationLink {
                                Text("Details")
                            } label: {
                                VStack {
                                    Image(systemName: "tv") // Replace with actual images
                                        .resizable()
                                        .scaledToFit()
                                        .frame(width: reader.size.width/3, height: 50)
                                        .padding()
                                        .background(Color.gray.opacity(0.2))
                                        .cornerRadius(10)
                                    Text("\(g.id)") // "List"
                                        .bold()
                                        .font(.subheadline)
                                }
                                .foregroundStyle(.white)
                            }
                        }
                    }
                    .scrollTargetLayout()
                }
                .scrollPosition(id: $scrollID)
                .onChange(of: scrollID) { oldVal, newVal in
                    print("\(String(describing: newVal))")
                }
            }
        }
    }