Search code examples
iosswiftswiftuiscrollviewscrollviewreader

SwiftUI ScrollViewReader scrollTo not working as expected


I am building a section of my app that allows users to train their skills in a sport by aiming for targets. Users can see their targets in a list. If more than 1 people are using this feature in my app, their training target lists are put next to each other in a scroll view. I want my app to automatically scroll to the currently active user. The code I use for this is:

func getTrainingTargetsScrollView(size: CGSize) -> some View {
    let players: [DSPlayer] = trainingController.currentExercise?.players ?? []
    
    return ScrollViewReader { value in
        ScrollView(.horizontal) {
            HStack(spacing: 0) {
                ForEach(players, id: \.id) { player in
                    ExerciseTable(player: player)
                        .frame(width: size.width)
                }
            }
        }
        .onReceive(trainingController.$currentPlayer, perform: { newValue in
            if let id = newValue?.id {
                withAnimation {
                    value.scrollTo(id)
                }
            }
        })
        .frame(height: size.height - 130)
    }
}

the onReceive gets triggered and I have verified that the players it gets passed are the right ones and have matching ID's with the players in the scrollview. However, it simply does not scroll.

Can anyone see what I'm doing wrong?


Solution

  • You need to give id to a view to scroll to, like:

    ForEach(players, id: \.id) { player in
        ExerciseTable(player: player)
            .frame(width: size.width)
            .id(player.id)              // << here !!
    }