SwiftUI Table - scroll to selected row

How would you scroll to a selected row in a Table?

I have implemented a find capability that successfully selects row(s) in a Table.

Sadly, often the selections aren't immediately visible, so users have to scroll up/down to confirm (my pinky promise isn't enough).

How would you (in effect or reality) scroll to a selected row?

Impl Dtl

  • Data is @Identifiable
  • Selection is @State selection = Set(<Data.Id>);
  • Table is Table(data, selection: $selection){ TableColumn("Col"){ ... }
  • A find Button successfully selection.insert(foundId)

The table shows the selected result either on screen or after user scroll. It's the after user scroll thing...who has time to for that? :)

All pretty vanilla stuff (I am enjoying SwiftUI a bunch).

Hopes + Dreams

The find Button is intended to grow selection - it selects a chunk of data, and then the user can decide to grow that chunk by clicking the find Button again.

Ideally, I'd like the Table to scroll to the first selection in each iteration of the "selection chunk", but honestly, auto-scrolling to selection.first at this point would be fantastic.

Any tips or tricks? I am new and stumped. Thx (MacOS, for now)

Answered by DTS Engineer in 742727022

Maybe:

https://developer.apple.com/documentation/swiftui/scrollviewreader

if you haven't looked at that already?

Accepted Answer

Maybe:

https://developer.apple.com/documentation/swiftui/scrollviewreader

if you haven't looked at that already?

holy smokes that worked. thank you so much. I really appreciate your help!

Soln

  1. Add an observable for to 'catch' when we need to scroll to a row / DataID: @State private var scrollToTableRow: DataIDClass?
  2. Expose a scrolling proxy at the outermost view container (in my case, above a Vstack):  some View { ScrollViewReader { (proxy:ScrollViewProxy) in VStack { ...beautiful UI here ... }
  3. Add a scrollToTableRow listener to the Table (nestled inside the Vstack): Table(...){ ... }.onChange(of: scrollToTableRow) { target in unwrap target, scrollToTableRow=nil, withAnimation {  proxy.scrollTo(target, anchor: .top) }
  4. In the find Button action, add scrollToTableRow=selection.first

I need to figure out a few minor details from here (setting focus to Table; remembering the first DataId in the next chunk). I am glad it worked, though I had my doubts! very cool. thank you thank you.

SwiftUI Table - scroll to selected row
 
 
Q