UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: scrollTo List ForEach Problem

Forums > SwiftUI

I have checked out the workaround (.id(UUID()) ) for the bug in scrollTo - List in iOS 16, but my project is using List ForEach and I cannot ge tthe scrolling to work (no crashes however). I just complete the 100 Days, so it is propbably a newbie dumb mistake? The commented out id I tried causes the compiler to timeout - unable to complete type checking... Thanks

ScrollViewReader { proxy in
                        List {
                            ForEach(scoredSkippers, id: \.self) { skip in
                                HStack {
                                    VStack {
                                        Image(systemName: "\(Int(skip.raceRawScore)).circle.fill")
                                        Text(skip.raceLetterScore == .๐Ÿ‘ ? "" : " \(skip.raceLetterScore.rawValue)").font(.caption2)
                                    }
                                    Spacer()
                                    Text(String(skip.sailNum))//.id(skip.index)
                                    Spacer()
                                }
                                .onLongPressGesture {
                                    isShowingRaceScore = skip
                                }
                                .listRowBackground(skip.raceLetterScore != .๐Ÿ‘ ? Color(.systemYellow) : nil)

                            }
                            .onMove(perform: move)
                        }
                        .id(UUID())
                        .scrollContentBackground(.hidden)
                        .background(.green.opacity(0.05))
                        .sheet(item: $isShowingRaceScore) { skip in
                            UpdateScoreView(thisRscore: skip)
                            }
                        .environment(\.editMode, .constant(.active))
                        .onChange(of: scoredSkippers.count) { _ in
                            proxy.scrollTo(scoredSkippers.count - 1)
                            }
                    }

1      

Just looking at the code and think you need the id that scrollTo on the HStack (row)

struct ContentView: View {
    var body: some View {
        ScrollViewReader { proxy in
            VStack {
                Button("Jump to #25") {
                    withAnimation {
                        proxy.scrollTo(25, anchor: .top)
                    }
                }

                List {
                    ForEach(0..<51, id: \.self) { i in
                        HStack {
                            Text("Example \(i)")
                            Spacer()
                            Image(systemName: "\(i).circle.fill")
                        }
                        .id(i) // <- need the id on rows
                    }
                }
            }
        }
    }
}

Try paste this in a test project to see

1      

I think @Nigel has the right answer.

Also, if you've finished the 100 Days of SwiftUI lessons, consider moving this code into your Skipper struct.

// Computed var for rowBackgroundColor

var rowBackgroundColor: Color { 
    raceLetterScore != .๐Ÿ‘ ?  .yellow : .white
}

Then in your ForEach view builder, you can use the computed var to clearly define what color your row background should be!

// Consider this instead...

HStack {
    // insert view code here...
    }
    .listRowBackground(skipper.rowBackgroundColor) // <--DECLARE what you want. Put the logic in your Skipper struct!

This simple change will make your code easier to read. It's more Swifty!

2      

Thanks for the input. 1) @Obelix I have a computed background color var now for rows in this view. 2) @NigelGee I managed to find the right combination of .id() and scrollTo for my situation based on your example:

ScrollViewReader { proxy in
                        List {
                            ForEach(scoredSkippers, id: \.id) { skip in
                                HStack {
                                    VStack {
                                        Image(systemName: "\(Int(skip.raceRawScore)).circle.fill")
                                        Text(skip.raceLetterScore == .๐Ÿ‘ ? "" : " \(skip.raceLetterScore.rawValue)").font(.caption2)
                                    }
                                    Spacer()
                                    Text(String(skip.sailNum))
                                    Spacer()
                                }.id(skip)
                                .onLongPressGesture {
                                    isShowingRaceScore = skip
                                }
                                .listRowBackground(skip.backgroundColor)

                            }
                            .onMove(perform: move)
                        }
                        .id(UUID())
                        .scrollContentBackground(.hidden)
                        .background(.green.opacity(0.05))
                        .sheet(item: $isShowingRaceScore) { skip in
                            UpdateScoreView(thisRscore: skip)
                            }
                        .environment(\.editMode, .constant(.active))
                        .onChange(of: scoredSkippers.count) { _ in
                            proxy.scrollTo(scoredSkippers.last)
                            }
                    } 

1      

Hacking with Swift is sponsored by RevenueCat

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.