SwiftUI List Selection On iPad

There’s an annoying problem that causes SwiftUI lists to lose their selection when running on iPadOS.

What’s The Problem

Here’s my setup. My root view has a navigation view containing a project list and items belonging to the selected project:

struct ContentView: View {
  var body: some View {
    NavigationView {
      ProjectList()
      Text("Select a project")
    }
  }
}

In landscape, this gives us the classic iPad two-pane split view:

iPad in landscape, sidebar shows project list with three projects, each  named new project with a timestamp, last project is selected. Detail view on the right shows a list of items in the selected project with two items each titled new item.

My project list and item list are similar. Here’s the ProjectList view:

struct ProjectList: View {
  @EnvironmentObject var store: ProjectStore
    
  var body: some View {
    List {
        ForEach(store.projects) { project in
            NavigationLink {
                ItemList(project: project)
            } label: {
                ProjectRow(project: project)
            }
        }
    }
    .navigationTitle("Projects")
  }    
}

The problem comes when I have enough projects that the list can scroll. If you select a row near the bottom of the list and then scroll the row loses selection when it disappears offscreen (FB9961092):

Animation showing selected row losing selection when scrolling offscreen

This type of problem makes me wonder if I’m doing something wrong but the Apple sample code suffers from the same problem.

I assume this problem is also the reason why restoring the selection state requires you to scroll the selection on screen, see scrolling with ScrollViewReader.

There’s a related problem if you need navigation in the detail view. As soon as you push a view onto the detail navigation stack the selection in the main/sidebar list loses selection (FB9961758).

Animation showing primary list losing selection when navigating in detail view

This second issue is fixed in iOS 16.

Workarounds?

I don’t have good workarounds for these issues other than falling back to UIKit. Are you using SwiftUI lists on iPadOS? What am I missing? Have you found a good workaround?

If you’d like Apple to fix this consider filing a feedback. You can find my feedback report, sample code and a screen recording of the problem at FB9961092 in my radar GitHub repository.